【发布时间】:2015-03-12 03:12:08
【问题描述】:
根据我使用的是基于 async/await 的代码还是基于 TPL 的代码,我在清理逻辑 CallContext 时遇到了两种不同的行为。
如果我使用以下异步/等待代码,我可以完全按照我的预期设置和清除逻辑 CallContext:
class Program
{
static async Task DoSomething()
{
CallContext.LogicalSetData("hello", "world");
await Task.Run(() =>
Debug.WriteLine(new
{
Place = "Task.Run",
Id = Thread.CurrentThread.ManagedThreadId,
Msg = CallContext.LogicalGetData("hello")
}))
.ContinueWith((t) =>
CallContext.FreeNamedDataSlot("hello")
);
return;
}
static void Main(string[] args)
{
DoSomething().Wait();
Debug.WriteLine(new
{
Place = "Main",
Id = Thread.CurrentThread.ManagedThreadId,
Msg = CallContext.LogicalGetData("hello")
});
}
}
以上输出如下:
{ Place = Task.Run, Id = 9, Msg = world }
{ Place = Main, Id = 8, Msg = }
注意Msg =,它表示主线程上的CallContext已被释放并且为空。
但是当我切换到纯 TPL/TAP 代码时,我无法达到同样的效果......
class Program
{
static Task DoSomething()
{
CallContext.LogicalSetData("hello", "world");
var result = Task.Run(() =>
Debug.WriteLine(new
{
Place = "Task.Run",
Id = Thread.CurrentThread.ManagedThreadId,
Msg = CallContext.LogicalGetData("hello")
}))
.ContinueWith((t) =>
CallContext.FreeNamedDataSlot("hello")
);
return result;
}
static void Main(string[] args)
{
DoSomething().Wait();
Debug.WriteLine(new
{
Place = "Main",
Id = Thread.CurrentThread.ManagedThreadId,
Msg = CallContext.LogicalGetData("hello")
});
}
}
以上输出如下:
{ Place = Task.Run, Id = 10, Msg = world }
{ Place = Main, Id = 9, Msg = world }
我能做些什么来强制 TPL 以与 async/await 代码相同的方式“释放”逻辑 CallContext?
我对@987654328@ 的替代品不感兴趣。
我希望修复上面的 TPL/TAP 代码,以便我可以在针对 .net 4.0 框架的项目中使用它。如果这在 .net 4.0 中是不可能的,我仍然很好奇它是否可以在 .net 4.5 中完成。
【问题讨论】:
标签: c# asynchronous task-parallel-library async-await task