Где хранить данные для текущего вызова WCF? Является ли ThreadStatic безопасным?
в то время как моя служба выполняется, многие классы должны будут получить доступ к пользователю.Текущий (это мой собственный класс пользователя). Могу ли я безопасно хранить _currentUser в [ThreadStatic] переменной? Делает ФОС повторного использования потоков? Если это так, то когда он будет очищать данные ThreadStatic? Если использование ThreadStatic небезопасно, где я должен поместить эти данные? Есть ли место внутри OperationContext.Тока где я могу хранить такие данные?
Edit 12/14/2009: Я могу утверждать, что с помощью ThreadStatic переменная не является безопасным. Потоки WCF находятся в пуле потоков, и переменная ThreadStatic никогда не инициализируется повторно.
2 ответов:
есть блог post что предполагает реализацию
IExtension<T>. Вы также можете взглянуть на это обсуждение.вот предлагаемая реализация:
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) { } }что вы могли бы использовать так:
WcfOperationContext.Current.Items["user"] = _currentUser; var user = WcfOperationContext.Current.Items["user"] as MyUser;
я обнаружил, что мы пропускаем данные или текущий контекст, когда мы делаем асинхронный вызов с несколькими переключениями потоков. Для обработки такого сценария можно попробовать использовать CallContext. Он должен использоваться в .NET remoting, но он также должен работать в таком сценарии.
установите данные в 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 ?
при вызове удаленного метода для объекта в другом домене приложения текущий класс CallContext создает LogicalCallContext, который перемещается вместе с вызовом в удаленное расположение.
только объекты, которые предоставляют ILogicalThreadAffinative интерфейс и хранятся в CallContext распространяются за пределами домена приложения.
Comments