HTTPContext sur les threads

J'ai besoin d'instancier un objet singleton par requête web, de sorte que les données sont traitées en une seule fois et est valable tout au long de la demande, j'ai été en utilisant HttpContext.Current.Items de partager des données lors de la requête HTTP, tout allait bien jusqu'à ce que nous avions besoin de l' singleton instance de l'objet entre plusieurs threads, la première chose que j'ai trouvé a été de passer de l'instance HttpContext pour le nouveau thread:

HttpContext context = HttpContext.Current;
ThreadPool.QueueUserWorkItem(callback =>
    {
        HttpContext.Current = context;
        //blah blah
    });

Qui je ne pense pas qu'est un thread-safe approche noter ici.

L'aide d'un Réflecteur, j'ai pensé HttpContext.Actuel.Les éléments utilise CallContext pour stocker les objets dans chaque thread logique. J'ai donc changé le singleton interface:

public static SingletonType SingletonInstance
{
    get { return CallContext.GetData(key) as SingletonType; }
    set { CallContext.SetData(key, value); }
}

Et il suffit de remplacer SingletonInstance lors du démarrage d'un nouveau thread! Le code fonctionne très bien, cependant, il semble que d'une certaine façon sous une lourde charge, CallContext.GetData(clé) renvoie la valeur null et l'application se bloque avec une référence nulle exception!

Que je pensais, si CallContext.GetData est atomique? Mais il ne semble pas approprié, le CallContext est thread spécifique de stockage de données et doit être atomique ou je suis à côté de la question!

Mon autre supposition est que la définition de la SingletonInstance (CallContext.SetData) arrive dans un thread pendant que CallContext.GetData s'exécute dans un autre comme noter ici mais je ne sais pas comment/pourquoi?

mise à jour:

Nous gardons une instance de chaque utilisateur en ligne dans un tableau sur le serveur. L'objet singleton est en fait une référence à l'objet représentant actuel de l'utilisateur. L'utilisateur actuel doit être unique et disponible dans chaque thread pour l'interrogation de bases de données, l'exploitation forestière, la gestion d'erreur et de plus, c'est comment il est fait:

public static ApplicationUser CurrentUser
{
    get { return CallContext.GetData("ApplicationUser") as ApplicationUser ; }
    set { CallContext.SetData("ApplicationUser", value); }
}
Un HttpContext se réfère à une seule requête Http. La mise en queue il quelque part un thread va vous poser quelques questions (comme vous l'avez de toute évidence trouvé). Peut-être que si vous décrire ce que c'est que vous êtes en train de faire, nous pouvons trouver une meilleure solution?
Le problème est simple, j'ai besoin d'une seule référence d'objet dans mon application iphone qui est instancié avec la demande (Demande BeginRequest peut-être), et il est vivant tout au long de la demande, et possible thread qui a commencé par la suite

OriginalL'auteur Kamyar Nazeri | 2012-03-31