我有一个简单的 async
和 await
我正在尝试完成的示例,但执行没有像我预期的那样返回给调用者。这是顶级方法:
protected async void MyDDL_SelectedIndexChanged(object sender, EventArgs e)
{
Task longRunningTask = LongRunningOperationAsync();
DoOtherStuff1();
DoOtherStuff2();
DoOtherStuff3();
await longRunningTask;
}
这是 LongRunningOperationAsync
未按预期工作并同步运行的方法:
private async Task LongRunningOperationAsync()
{
var myValues = await GetStuffViaLongRunningTask();
//Code to work with myValues here...
}
这里是GetStuffViaLongRunningTask
的定义
private async Task<IList<MyClass>> GetStuffViaLongRunningTask()
{
//...Calls to get and build up IList<MyClass>
return results;
}
问题是上面的代码没有返回调用者并开始运行DoOtherStuff1();
方法如我所料。但是,不是调用我自己的方法并将其替换为对 await Task.Delay(10000);
的调用如同所有简单示例所示,代码按预期工作:
private async Task LongRunningOperationAsync()
{
//Returns to caller as expected:
await Task.Delay(10000);
}
使用上面代码的调用者有longRunningTask
用WaitingForActivation
作为其状态而不是 RanToCompletion
, 显示它仍在处理中。
你可能会说我的 GetStuffViaLongRunningTask()
方法运行得如此之快,我只是看不到结果。但是,它总是需要 3-7 秒才能运行,您可以在调试时知道调用正在阻塞并且同步。
我在这里做错了什么,所以我调用 LongRunningOperationAsync()
到达 await
时不异步工作打电话的话LongRunningOperationAsync
在那个方法里?
最佳答案
假设//...Calls to get and build up IList<MyClass>
是同步 CPU 绑定(bind)工作,问题是 GetStuffViaLongRunningTask
在它结束或达到第一个 await
之前不会返回称呼。您应该在该方法上收到编译器警告,因为它是 async
没有 await
的方法
相反,该方法根本不应该是 async
, 以清楚地向调用者表明这是同步工作。只需将签名调整为:
private IList<MyClass> GetStuffViaLongRunningTask()
然后在调用它时使用 Task.Run
确保长时间运行的 CPU 绑定(bind)工作在另一个线程中完成:
private async Task LongRunningOperationAsync()
{
var myValues = await Task.Run(() => GetStuffViaLongRunningTask());
//Code to work with myValues here...
}
关于c# - async 和 await 没有按预期返回调用者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19232575/