Где хранить данные для текущего вызова WCF? Безопасен ли ThreadStatic?
Пока моя служба выполняется, многим classам необходимо будет получить доступ к User.Current (это мой собственный class User). Можно ли безопасно хранить _currentUser в переменной [ThreadStatic]
? Использует ли WCF свои streamи? Если это так, когда он очистит данные ThreadStatic? Если использование ThreadStatic небезопасно, где я должен помещать эти данные? Есть ли место внутри OperationContext.Current, где я могу хранить такие данные?
Редактирование 12/14/2009: могу утверждать, что использование переменной ThreadStatic небезопасно. Потоки WCF находятся в пуле streamов, и переменная ThreadStatic никогда не повторно инициализируется.
- Существующее соединение было принудительно закрыто удаленным хостом - WCF
- Событие запуска приложения WCF
- Получение IP-адреса клиента в WCF 3.0
- Формат тела веб-службы RESTful
- Ошибка пользовательского исключения веб-службы WCF для клиента
- Как включить трассировку WCF?
- HTTP не смог зарегистрировать URL http: // +: 8000 / HelloWCF /. У вашего процесса нет прав доступа к этому пространству имен
- Как добавить настраиваемый HTTP-заголовок для каждого вызова WCF?
- Несоответствие ContractFilter при исключении EndpointDispatcher
- Служба WCF, как увеличить таймаут?
- Увеличение значения тайм-аута в службе WCF
Есть сообщение в блоге, в котором предлагается реализовать 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.