Con*_*eak 14 .net c# asp.net asynchronous async-await
让我们说我只想要一种方法来运行async.
所以我有一个async如下方法:
public async Task Load(){
Task task1 = GetAsync(1);
Task task2 = GetAsync(2);
Task task3 = GetAsync(3);
var data1 = await task1; // <--Freezes here when called from GetSomethingElse()
var data2 = await task2;
var data3 = await task3;
..process data..
}
Run Code Online (Sandbox Code Playgroud)
然后我试图async在另一个方法中将该方法称为任务,并希望它等到特定的async代码片段完成.问题是它不是.当它到达第一个时await,Load()它就没有完成加载.调试器变为空白,不会出现其他错误.
是一种async能够从非async方法调用的方法吗?有一个原因我不需要这个特定的任务async,但Load()我做的功能.
public void GetSomethingElse(){
var task1 = Load().Wait();
}
Run Code Online (Sandbox Code Playgroud)
这怎么可能?
我试过甚至改变Load()使用的方法var data = task1.Wait()等,而不是await,仍然没有区别,无论我尝试哪种方式.如果有人可以提供帮助,将不胜感激.
i3a*_*non 11
你的手上可能有僵局.您正在阻止线程使用Wait()需要该线程完成的任务,因为SynchronizationContextASP.Net中也使用了一个线程(也在GUI环境中).
您应该使用ConfigureAwait(false)告诉awaiter不要捕获该上下文.这是第一次做到这一点,await因为其余的将无法SynchronizationContext捕获:
public async Task Load()
{
Task task1 = GetAsync(1);
Task task2 = GetAsync(2);
Task task3 = GetAsync(3);
var data1 = await task1.ConfigureAwait(false);
var data2 = await task2;
var data3 = await task3;
//..process data.
}
Run Code Online (Sandbox Code Playgroud)
但是,建议始终使用,ConfigureAwait除非您想要捕获,SynchronizationContext所以更好的标准是这样的:
public async Task Load()
{
Task task1 = GetAsync(1);
Task task2 = GetAsync(2);
Task task3 = GetAsync(3);
var data1 = await task1.ConfigureAwait(false);
var data2 = await task2.ConfigureAwait(false);
var data3 = await task3.ConfigureAwait(false);
//..process data.
}
Run Code Online (Sandbox Code Playgroud)
在您的情况下,您希望在完成所有任务后继续执行任务,您应该使用Task.WhenAll而不是await单独执行每项任务:
public async Task Load()
{
await Task.WhenAll(GetAsync(1), GetAsync(2), GetAsync(3)).ConfigureAwait(false);
// process data.
}
Run Code Online (Sandbox Code Playgroud)
注意:通常不建议通过异步执行同步,因为它没有任何好处(您在整个操作期间阻塞了一个线程)并且可能导致死锁(如此).
| 归档时间: |
|
| 查看次数: |
1061 次 |
| 最近记录: |