将集合投影为任务并等待所有完成
Project a collection as task and wait for all completion
我正在尝试并行化从集合发出的工作,并等待所有任务完成。
这里基本上是我所拥有的:
public Task<int> DoWorkAsync(int arg){
return Task.Factory.StartNew(()=> {
Thread.Sleep(1000);
return arg*2;
});
}
public async void DoAllWorks(){
ICollection<int> workToDo = GetSomeWorkFromSomewhere();
IEnumerable<Task<int>> tasks = workToDo.Select(i=> DoWorkAsync(i));
int[] results = await Task.WhenAll(tasks);
Debug.Write(results.Sum()); // Never called
}
public void Main(){
DoAllWorks();
// rest of code, which is called
OtherMethods();
}
但是,WhenAll
方法会立即退出并运行其余代码,即使仍有工作在执行。
如何解决?
您正在使用 async void
,它应该只用于事件处理程序。
当您使用 async void
时,您不能等待 async
操作完成(同步或异步)。这意味着它 "fires" DoAllWorks
并继续前进,因为它不知道 DoAllWorks
何时完成。 await Task.WhenAll(tasks)
inside DoAllWorks
等待得很好,但是调用方法已经继续了。
你应该 return 一个任务,而不是你可以 await
或 Wait()
在这种情况下,因为 Main
不能是 async
本身。
public void Main()
{
DoAllWorks().Wait();
// rest of code, which is called
OtherMethods();
}
public async Task DoAllWorks()
{
ICollection<int> workToDo = GetSomeWorkFromSomewhere();
IEnumerable<Task<int>> tasks = workToDo.Select(i=> DoWorkAsync(i));
int[] results = await Task.WhenAll(tasks);
Debug.Write(results.Sum());
}
除事件处理程序外,您不应使用 async void。如果你 return 一个任务,你可以在主方法中使用 await
关键字或类似的方法等待它:
DoAllWorks().Wait();
仅供参考,您不需要使用 Thread.Sleep(1000);
。您可以稍微重写代码以更符合 async/await
构造
return Task.Run(async ()=> {
await Task.Delay(1000);
return arg*2;
});
我正在尝试并行化从集合发出的工作,并等待所有任务完成。
这里基本上是我所拥有的:
public Task<int> DoWorkAsync(int arg){
return Task.Factory.StartNew(()=> {
Thread.Sleep(1000);
return arg*2;
});
}
public async void DoAllWorks(){
ICollection<int> workToDo = GetSomeWorkFromSomewhere();
IEnumerable<Task<int>> tasks = workToDo.Select(i=> DoWorkAsync(i));
int[] results = await Task.WhenAll(tasks);
Debug.Write(results.Sum()); // Never called
}
public void Main(){
DoAllWorks();
// rest of code, which is called
OtherMethods();
}
但是,WhenAll
方法会立即退出并运行其余代码,即使仍有工作在执行。
如何解决?
您正在使用 async void
,它应该只用于事件处理程序。
当您使用 async void
时,您不能等待 async
操作完成(同步或异步)。这意味着它 "fires" DoAllWorks
并继续前进,因为它不知道 DoAllWorks
何时完成。 await Task.WhenAll(tasks)
inside DoAllWorks
等待得很好,但是调用方法已经继续了。
你应该 return 一个任务,而不是你可以 await
或 Wait()
在这种情况下,因为 Main
不能是 async
本身。
public void Main()
{
DoAllWorks().Wait();
// rest of code, which is called
OtherMethods();
}
public async Task DoAllWorks()
{
ICollection<int> workToDo = GetSomeWorkFromSomewhere();
IEnumerable<Task<int>> tasks = workToDo.Select(i=> DoWorkAsync(i));
int[] results = await Task.WhenAll(tasks);
Debug.Write(results.Sum());
}
除事件处理程序外,您不应使用 async void。如果你 return 一个任务,你可以在主方法中使用 await
关键字或类似的方法等待它:
DoAllWorks().Wait();
仅供参考,您不需要使用 Thread.Sleep(1000);
。您可以稍微重写代码以更符合 async/await
构造
return Task.Run(async ()=> {
await Task.Delay(1000);
return arg*2;
});