Где хранить данные для текущего вызова WCF? Безопасен ли ThreadStatic?

Пока моя служба выполняется, многим classам необходимо будет получить доступ к User.Current (это мой собственный class User). Можно ли безопасно хранить _currentUser в переменной [ThreadStatic] ? Использует ли WCF свои streamи? Если это так, когда он очистит данные ThreadStatic? Если использование ThreadStatic небезопасно, где я должен помещать эти данные? Есть ли место внутри OperationContext.Current, где я могу хранить такие данные?

Редактирование 12/14/2009: могу утверждать, что использование переменной ThreadStatic небезопасно. Потоки WCF находятся в пуле streamов, и переменная ThreadStatic никогда не повторно инициализируется.

Есть сообщение в блоге, в котором предлагается реализовать IExtension . Вы также можете взглянуть на эту дискуссию .

Вот предлагаемая реализация:

 public class WcfOperationContext : IExtension { private readonly IDictionary items; private WcfOperationContext() { items = new Dictionary(); } public IDictionary Items { get { return items; } } public static WcfOperationContext Current { get { WcfOperationContext context = OperationContext.Current.Extensions.Find(); if (context == null) { context = new WcfOperationContext(); OperationContext.Current.Extensions.Add(context); } return context; } } public void Attach(OperationContext owner) { } public void Detach(OperationContext owner) { } } 

Что вы можете использовать так:

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

Я обнаружил, что мы пропускаем данные или текущий контекст, когда делаем asynchronous вызов с несколькими переключениями streamов. Чтобы справиться с таким сценарием, вы можете попробовать использовать CallContext. Предполагается, что он используется в удалении .NET, но он также должен работать в таком сценарии.

Задайте данные в CallContext:

 DataObject data = new DataObject() { RequestId = "1234" }; CallContext.SetData("DataSet", data); 

Получение общих данных из CallContext:

 var data = CallContext.GetData("DataSet") as DataObject; // Shared data object has to implement ILogicalThreadAffinative public class DataObject : ILogicalThreadAffinative { public string Message { get; set; } public string Status { get; set; } } 

Почему ILogicalThreadAffinative?

Когда удаленный вызов метода выполняется для объекта в другом AppDomain, текущий class CallContext генерирует LogicalCallContext, который перемещается вместе с вызовом удаленного места.

Только объекты, которые раскрывают интерфейс ILogicalThreadAffinative и хранятся в CallContext, распространяются вне AppDomain.

Давайте будем гением компьютера.