当我的服务执行时,许多类需要访问User.Current(这是我自己的User类)。我可以安全地将_currentUser存储在[ThreadStatic]
变量中吗? WCF是否重用其线程?如果是这种情况,它什么时候会清理ThreadStatic数据?如果使用ThreadStatic不安全,我应该把数据放在哪里?在OperationContext.Current中是否有一个可以存储这种数据的地方?
编辑12/14/2009:我可以断言使用ThreadStatic变量并不安全。 WCF线程在线程池中,而ThreadStatic变量从不重新初始化。
答案 0 :(得分:84)
有一个博客post建议实施IExtension<T>
。您也可以查看此discussion。
以下是建议的实施方案:
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;
答案 1 :(得分:0)
不添加额外的驱动类的替代解决方案。
OperationContext operationContext = OperationContext.Current;
operationContext.IncomingMessageProperties.Add("SessionKey", "ABCDEFG");
获得价值
var ccc = aaa.IncomingMessageProperties["SessionKey"];
就这样
答案 2 :(得分:-1)
我发现当我们使用多线程切换进行异步调用时,我们会错过数据或当前上下文。要处理这种情况,您可以尝试使用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中的对象进行远程方法调用时,当前的CallContext类会生成一个LogicalCallContext,它随着对远程位置的调用而移动。
只有公开ILogicalThreadAffinative接口并存储在CallContext中的对象才会传播到AppDomain之外。