【发布时间】:2013-10-16 08:34:29
【问题描述】:
我正在寻找一个执行上下文,它可以很好地与async/await 和 TPL 同时以下列方式(预期行为):
async Task<string> ReadContext(string slot)
{
// Perform some async code
...
return Context.Read(slot);
}
(1) 与async/await玩得很好
Context.Store("slot", "value");
await DoSomeAsync();
Assert.AreEqual("value", Context.Read("slot"));
Context.Store("slot", "value");
var value = await ReadContext("slot");
Assert.AreEqual("value", value);
(2) 与Task.Run()玩得很好
Context.Store("slot", "value");
var task = Task.Run(() => ReadContext("slot"));
Assert.IsNull(task.Result);
(3) 与期待已久的Task 玩得很好
Context.Store("slot", "value");
var value = await Task.Run(() => ReadContext("slot"));
Assert.AreEqual("value", value);
(3) 不是必需的,但会很好。我现在使用CallContext,但它在 (2) 处失败,因为即使在手动运行的任务中也可以访问存储在其中的值,即使在使用 Task.Factory.StartNew(..., LongRunning) 运行的任务中也应该强制在单独的线程。
有没有办法做到这一点?
【问题讨论】:
-
在我看来不像一个普通的Execution Ctx。你能详细说明一下吗?
-
我不明白 (2) 处的
Assert.IsNull(这是对 task.Result 的阻塞等待)。你的意思是像Assert.IsNull(task.Result, "should be null")这样的东西吗? -
基本上,我需要一个地方来在 ASP.NET 应用程序中存储 NHibernate 会话。如果我在请求上下文中,
HttpContext可以正常工作(并尊重async/await),但是一旦我跳入手动运行的任务,它就无法使用。无论如何,现在我意识到我想要的可能是不可能的,因为当我手动启动任务时,环境不知道我是否要等待它。 -
@Noseratio 你说得对,已编辑。
-
我很惊讶
CallContext像 (2) 一样通过Task.Run传递给池线程,你确定吗?无论如何,如果我没有遗漏任何东西,现在对 (2) 和 (3) 的要求对我来说看起来是相互排斥的。
标签: c# asynchronous task-parallel-library async-await executioncontext