【发布时间】:2017-10-30 23:28:22
【问题描述】:
我有一个异步方法,我想提供 TaskCreationOptions.LongRunning 标志。这很容易通过包装 Task 调用的非异步方法来实现:
void Foo() { Thread.Sleep(5000); }
var task = Task.Factory.StartNew(Foo, TaskCreationOptions.LongRunning);
Console.WriteLine(task.CreationOptions);
// LongRunning
或多种变体中的任何一种(Task.Run、新任务等)。但是,似乎没有办法将方法定义为异步并返回Task:
async Task FooAsync() { await Task.Delay(TimeSpan.FromSeconds(10.0)); }
Task fooTask = FooAsync();
Console.WriteLine(FooTask.CreationOptions);
// None
尝试将其包装在长时间运行的任务中也是一个空启动器:
async Task FooAsync() { await Task.Delay(TimeSpan.FromSeconds(10.0)); }
Task<Task> wrapTask = Task.Factory.StartNew(FooAsync, TaskCreationOptions.LongRunning);
Console.WriteLine(wrapTask.CreationOptions);
// LongRunning
Console.WriteLine(wrapTask.Unwrap().CreationOptions);
// None
在这种情况下,wrapTask 确实是LongRunning,但它几乎立即返回(在FooAsync 调用await Task.Delay(...) 之后不久),因此设置该标志实际上可能是不可取的。我最终想要等待的是wrapTask.Unwrap()。
在我的测试中我发现,事实上,FooAsync 中的代码在从await 返回后在线程池线程中执行。正常情况下,它在调用线程上调用,但之后不会尝试在调用线程上恢复执行。
我希望这可以通过方法属性来控制,但我找不到任何可以在这里提供帮助的东西。是否可以更改编译器为异步方法生成的创建选项?尝试一下有意义吗?
【问题讨论】:
标签: c# .net async-await