Different exception handling between Task.Run and Task.Factory.StartNew

不想你离开。 提交于 2019-12-03 05:47:00

Your problem is that StartNew doesn't work like Task.Run with async delegates. The return type of StartNew is Task<Task> (which is convertible to Task). The "outer" Task represents the beginning of the method, and the "inner" Task represents the completion of the method (including any exceptions).

To get to the inner Task, you can use Unwrap. Or you can just use Task.Run instead of StartNew for async code. LongRunning is just an optimization hint and is really optional. Stephen Toub has a good blog post on the difference between StartNew and Run and why Run is (usually) better for async code.

Update from @usr comment below: LongRunning only applies to the beginning of the async method (up until the first incomplete operation is awaited). So it's almost certainly better all around to use Task.Run in this case.

I'll pull some of my comments into an answer because they turned out to be helpful:

LongRunning is identical to forcing a new thread to be created in practice. And your async method is probably not on that thread for a long time (it is taken off at the first await point). You don't want LongRunning in this case.

It does not matter how long the async method runs. The thread is destroyed at the very first await (that operates on a non-completed task).

Can the compiler use this hint in any way? The compiler is generally unable to analyze your code in any major way. Also the compiler does not know anything about the TPL. The TPL is a library. And this library will just always launch a new thread. Specify LongRunning iff your task will almost always burn 100% CPU for multiple seconds or will block for multiple seconds with very high probability.

My guess is you don't want LongRunning here because if you're blocking, why are you using async in the first place? async is about not blocking but getting off the thread.

It should be possible when you first Unwrap the task:

await RunTaskAsync().Unwrap();

Or alternatively:

await await RunTaskAsync();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!