Can async methods have expensive code before the first 'await'?

不羁岁月 提交于 2019-12-01 03:26:34

As Reed says, it really depends on the context. The code has to run at some point - but depending on the context, it may end up being run on a thread pool thread instead of some critical one.

Rather than using Task.Run, I'd use TaskEx.Yield:

public async Task Foo()
{
    await TaskEx.Yield();
    // Do expensive stuff
}

As far as I'm aware, that's basically a way of immediately returning to the caller, but allowing the rest of the async method to be scheduled straightaway. If you're in something like a Windows Forms UI thread, there's no point in doing this as you'll be back to the UI thread (and running expensive code there) immediately - but it would make sense if you're in a context where the current thread shouldn't be blocked, but continuations are run on another thread.

It's not necessarily bad, but it may have unexpected consequences. If the caller expects that the code will behave completely asynchronously, the expensive code will run synchronously. This will cause it to behave partly like a synchronous method, but also asynchronously, which is kind of the worst of both worlds (extra complexity from asynchrony without the repsoniveness...)

If possible, I would recommend trying to have as little "expensive" code leading to the first await. Using Task.Run (or TaskEx.Run in the CTP) to wrap the expensive code, or moving the expensive code into its own asynchronous method (upon which you could await) would be beneficial in this case.

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