在第一个await被调用之前,在异步方法的开头有昂贵的代码是不是很糟糕?这个代码应该用一个包裹TaskEx.Run吗?
public async Task Foo()
{
// Do some initial expensive stuff.
// ...
// First call to an async method with await.
await DoSomethingAsync;
}
Run Code Online (Sandbox Code Playgroud) 如果这个问题是基于意见的,请提前道歉.这里已经讨论了缺少不捕获执行上下文的Task.Yield版本.显然,这个功能在早期版本的Async CTP中以某种形式出现,但由于它很容易被滥用而被删除.
IMO,这样的功能可能很容易被滥用Task.Run.这就是我的意思.想象一下,有一个等待的SwitchContext.YieldAPI可以调度ThreadPool上的延续,因此执行将始终在与调用线程不同的线程上继续.我可以在下面的代码中使用它,它从UI线程启动一些CPU绑定的工作.我认为这是一种在池线程上继续CPU绑定工作的便捷方式:
class Worker
{
static void Log(string format, params object[] args)
{
Debug.WriteLine("{0}: {1}", Thread.CurrentThread.ManagedThreadId, String.Format(format, args));
}
public async Task UIAction()
{
// UI Thread
Log("UIAction");
// start the CPU-bound work
var cts = new CancellationTokenSource(5000);
var workTask = DoWorkAsync(cts.Token);
// possibly await for some IO-bound work
await Task.Delay(1000);
Log("after Task.Delay");
// finally, get the result of the CPU-bound work
int c = await workTask;
Log("Result: {0}", …Run Code Online (Sandbox Code Playgroud)