web-dev-qa-db-fra.com

Où stocker les données pour l'appel en cours WCF? ThreadStatic est-il sûr?

Pendant que mon service s'exécute, de nombreuses classes devront accéder à User.Current (c'est ma propre classe User). Puis-je stocker en toute sécurité _currentUser dans une variable [ThreadStatic]? Est-ce que WCF réutilise ses threads? Si tel est le cas, quand va-t-il nettoyer les données ThreadStatic? Si utiliser ThreadStatic n’est pas sûr, où devrais-je mettre ces données? Y at-il un endroit dans OperationContext.Current où je peux stocker ce type de données?

Edit 12/14/2009: Je peux affirmer que l'utilisation d'une variable ThreadStatic n'est pas sûre. Les threads WCF sont dans un pool de threads et la variable ThreadStatic n'est jamais réinitialisée.

53
Sylvain

Il existe un blog post qui suggère de mettre en œuvre un IExtension<T> . Vous pouvez aussi jeter un oeil à cette discussion discussion .

Voici une implémentation suggérée:

public class WcfOperationContext : IExtension<OperationContext>
{
    private readonly IDictionary<string, object> items;

    private WcfOperationContext()
    {
        items = new Dictionary<string, object>();
    }

    public IDictionary<string, object> Items
    {
        get { return items; }
    }

    public static WcfOperationContext Current
    {
        get
        {
            WcfOperationContext context = OperationContext.Current.Extensions.Find<WcfOperationContext>();
            if (context == null)
            {
                context = new WcfOperationContext();
                OperationContext.Current.Extensions.Add(context);
            }
            return context;
        }
    }

    public void Attach(OperationContext owner) { }
    public void Detach(OperationContext owner) { }
}

Ce que vous pourriez utiliser comme ça:

WcfOperationContext.Current.Items["user"] = _currentUser;
var user = WcfOperationContext.Current.Items["user"] as MyUser;
84
Darin Dimitrov

Une solution alternative sans ajouter de classe supplémentaire.

    OperationContext operationContext = OperationContext.Current;
    operationContext.IncomingMessageProperties.Add("SessionKey", "ABCDEFG");

Pour obtenir la valeur

var ccc = aaa.IncomingMessageProperties["SessionKey"];

C'est tout

0
ValidfroM