AsyncLocal允许我们将上下文数据保存在异步控制流上。这非常简洁,因为以下所有简历(即使在另一个线程上)都可以检索和修改环境数据(AsyncLocal on MSDN)。
有没有办法离开'子任务的当前异步本地上下文,从而创建一个新的?
AsyncLocal<string> Data = new AsyncLocal<string>();
Data.Value = "One";
Task.Factory.StartNew( () =>
{
string InnerValue = Data.Value;
//InnerValue equals to "One", I need it to be null.
} );
在上面的示例中,内部任务与外部控制流共享AsyncLocal上下文。有没有办法强制执行新的上下文?
更新:为了在这里解决我的问题,以下工作就像一个魅力(尽管事实上它并没有完全重置上下文):
AsyncLocal<string> Data = new AsyncLocal<string>();
Data.Value = "One";
Task.Factory.StartNew( () =>
{
Data.Value = null;
string InnerValue = Data.Value;
//InnerValue equals to null now.
} );
string OuterValue = Data.Value; //Stays "one" even after the inner change.
答案 0 :(得分:2)
您可以使用ExecutionContext.SuppressFlow
:
AsyncLocal<string> Data = new AsyncLocal<string>();
Data.Value = "One";
using (ExecutionContext.SuppressFlow())
{
Task.Factory.StartNew( () =>
{
string InnerValue = Data.Value;
//InnerValue is null.
} );
}
请注意,这可能会产生副作用,例如不再产生正确的堆栈跟踪。但是,由于您忽略了StartNew
的结果,也就是说,您似乎对实际上拥有一个流程不感兴趣,因此这是正确的做法。
或者,为了更符合您自己的更新中的解决方案,请记住AsyncLocal
是作用域的,即,如果您在嵌套异步操作中设置该值,则它不会影响外部函数中的值。这意味着您可以在嵌套操作中重置AsyncLocal
的第一件事,而不会破坏外部操作的值。
答案 1 :(得分:-3)
您必须使用ThreadLocal
AsyncLocal<string> Data = new AsyncLocal<string>();
ThreadLocal<string> Data1 = new ThreadLocal<string>();
Data.Value = "One";
Data1.Value = "Two";
Task.Factory.StartNew(() =>
{
string InnerValue = Data.Value; //InnerValue equals to "One",
string InnerValue1 = Data1.Value; //InnerValue1 equals to null,
});
希望有所帮助