Mik*_*e E 2 .net c# async-await
我有一个异步方法,我想给这个TaskCreationOptions.LongRunning标志.使用包装调用的非异步方法很容易Task:
void Foo() { Thread.Sleep(5000); }
var task = Task.Factory.StartNew(Foo, TaskCreationOptions.LongRunning);
Console.WriteLine(task.CreationOptions);
// LongRunning
Run Code Online (Sandbox Code Playgroud)
或者任何一种变体(Task.Run,new Task等).但是,似乎没有办法将方法定义为async并返回Task:
async Task FooAsync() { await Task.Delay(TimeSpan.FromSeconds(10.0)); }
Task fooTask = FooAsync();
Console.WriteLine(FooTask.CreationOptions);
// None
Run Code Online (Sandbox Code Playgroud)
尝试将其包装在长时间运行的任务中也是一个空启动:
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
Run Code Online (Sandbox Code Playgroud)
在这种情况下,wrapTask确实如此LongRunning,但它几乎立即返回(FooAsync调用后不久await Task.Delay(...)),因此设置该标志实际上可能是不合需要的.我最终想要等待的是wrapTask.Unwrap().
在我的测试中,我发现事实上,代码在FooAsync从一个线程池线程返回之后执行await.通常,它是在调用线程上调用的,但它不会尝试在调用线程上继续执行.
我希望这可以通过方法属性来控制,但是我找不到任何可以帮助的方法.是否可以更改编译器为异步方法生成的创建选项?尝试是否有意义?
你的问题没有任何意义,因为一个async方法不是一个线程.它不启动一个线程,它不代表一个线程,它没有任何与线程相关的有用方式.
一种async方法是异步仅向它等待程度其他异步操作.就这样.只有在那些操作作为实际线程启动的情况下(例如Task.Run()),甚至会有一个线程描述为长时间运行,并且在这种情况下,您可以在调用时访问所需的选项Task.Run().
如果您的async方法本身实际上是长期运行的,那么为什么要async首先使用该方法?您可以在其他异步操作上使用同步等待来保持线程.恕我直言,这是不理想的,但你已经接受了你将长时间坚持这个线程,所以为什么不更长?
或者,也许你只是意味着等待可能需要很长时间.在这种情况下,使用该选项甚至是不正确的LongRunning,因为这告诉调度程序您的操作将持续一段时间的线程.您的投诉似乎是"代码...在从await" 返回后在线程池线程中执行".但是你的代码在等待时实际上并没有持有一个线程,所以它并没有真正长时间运行.
如果你有你的方法的元素做实际上是长时间通过产生线程运行之前await,你不希望阻止在方法以外等待当前线程,那么在我看来,你应该重构那些部分的在async其长期运行到他们自己的方法,你可以通过执行方法Task.Run().然后,您的async方法可以等待那些不阻塞当前线程的方法,并且您可以向线程调度程序指示操作的那些特定部分是长时间运行的(即通过将选项传递给Task.Run()).
| 归档时间: |
|
| 查看次数: |
544 次 |
| 最近记录: |