开始编辑
执行此操作(4.5之前)的“正确”方法是使用此处概述的SynchronizationContext:http://msdn.microsoft.com/en-us/magazine/gg598924.aspx
我相信在4.5中,使用async / await关键字自动处理SynchronizationContext,但是还没有做足够的工作来确认。
在4.0中,您可能希望利用“TaskScheduler.FromCurrentSynchronizationContext”来捕获当前线程的上下文(在我的例子中,这将包括HttpContext,但BCL的各个部分提供类似的结构)。
结束编辑
主要问题是:
以下是与任务共享“上下文”的“安全”机制吗?
在我的用例中,没有太多细节,不可能直接将上下文推送到操作中。
public static class ContextCaller{
[ThreadStatic]
public static object SharedState;
public static Task InvokeWithContext(this Action theAction){
//We're still running in the "outer" context,
//so we can collect a variable and store it in the thread-static
//field by closing it into the task.
var context = new object();
var t = new Task(()=>{
try{
//close in the context
SharedState = context;
theAction();
}
finally{
//teardown the shared state.
SharedState = null;
}
});
t.Start();
return t;
}
}
现在客户端代码:
//client code:
Action doWork = ()=>{
var state = ContextCaller.SharedState;
//do work on state, potentially throwing an exception in the process.
};
//cause the task to be invoked with some data available only on this thread.
doWork.InvokeWithContext();
基于我对任务和线程之间关系的理解,上面应该是安全的,因为:
除了明确地将参数关闭到“theAction”之外,还有其他更好的模式来定义任务上下文吗?
答案 0 :(得分:1)
我没有看到任何技术原因导致您的代码无法正常工作。
但我也认为这样做是不好的做法,只有在没有其他方法的情况下我才会使用这样的东西。我认为添加另一个方法的重载需要Action<object>
(甚至更好,使用强类型参数)不应该是一个重大的改变。