使用 Task.Run 时避免捕获当前执行上下文
我想创建/运行任务而不捕获当前执行上下文。这可能吗?
考虑以下示例:
private static readonly AsyncLocal<object> AsyncLocal = new AsyncLocal<object>();
[TestMethod]
public void TaskRunCapturesContext()
{
AsyncLocal.Value = 1;
var task = Task.Run(static async () =>
{
await Task.Delay(1).ConfigureAwait(false);
Console.WriteLine(AsyncLocal.Value); // Prints "1", expected is "" <-- Problem HERE
AsyncLocal.Value = 2;
Console.WriteLine(AsyncLocal.Value); // Prints "2", expected is "2"
});
Task.WaitAll(task);
Console.WriteLine(AsyncLocal.Value); // Prints "1", expected is "1"
}
是否可以使第一个 Console.WriteLine(AsyncLocal.Value);
打印 ""
而不是 "1"
(因为 AsyncLocal.Value 为 null/未初始化)?
我还尝试了更明确的 Task.Factory 方法的所有重载,但我找不到解决方案。从源代码中还可以看出,Task.Run(Action) 转换为对 Task.InternalStartNew(null, action, null, ..)
的调用,该调用显式传递 null
作为 state
参数,所以我没有看到更明确的方法。
提前致谢
I would like to create/run a task without capturing the current execution context. Is this possible?
Consider the following sample:
private static readonly AsyncLocal<object> AsyncLocal = new AsyncLocal<object>();
[TestMethod]
public void TaskRunCapturesContext()
{
AsyncLocal.Value = 1;
var task = Task.Run(static async () =>
{
await Task.Delay(1).ConfigureAwait(false);
Console.WriteLine(AsyncLocal.Value); // Prints "1", expected is "" <-- Problem HERE
AsyncLocal.Value = 2;
Console.WriteLine(AsyncLocal.Value); // Prints "2", expected is "2"
});
Task.WaitAll(task);
Console.WriteLine(AsyncLocal.Value); // Prints "1", expected is "1"
}
Is it possible to make the first Console.WriteLine(AsyncLocal.Value);
print ""
instead of "1"
(because AsyncLocal.Value is null/not initialized)?
I also played around with all overloads of the more explicit Task.Factory-method, but I couldn't find a solution. Form the source it can also be seen that Task.Run(Action) translates into a call to Task.InternalStartNew(null, action, null, ..)
which explicitly passes null
as state
-argument, so I dont see a way I could be more explicit.
Thanks in advance
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
感谢 @canton7 的评论,答案相当简单:您可以使用 ExecutionContext.SuppressFlow。
更正了上面的示例:
Thanks to @canton7's comment the answer is rather simple: You can prevent the the ExecutionContext from flowing by using ExecutionContext.SuppressFlow.
Corrected above sample: