我有一个小查询。
我承认在。net 4.5之前我很少使用多线程,但是有了新的async/await
功能,我决定试一试。我开始尝试,一切似乎都很好,但我无法找到一个解决我的"问题"在网络上的任何地方。
所以每个人都解释了await
如何与。net平台的新转换方法(例如WriteAsync()
, ReadAsync()
等)一起使用,但是如果我想将它用于我自己的方法呢?例如,假设我正在执行一个非常昂贵的计算,并希望我的所有4个核心都能处理它。我会有类似这样的内容:
async Task DoLotsOfWork<T>(T[] data, int start, int end)
{
//Do very expensive work
}
但是因为我没有await
关键字,所以该方法只是作为同步方法处理。我想从外部调用它4次,这样它就可以在我所有的核心上运行,而我向用户显示一些明智的东西(例如:"请等待…")。我能够找出的唯一解决方案是在方法开始时添加await Task.Yield();
。像这样:
async Task DoLotsOfWork<T>(T[] data, int start, int end)
{
await Task.Yield();
//Do very expensive work
}
在这种情况下,该方法将按照我所期望的方式运行。但是有没有更好的解决办法呢?我觉得这应该比完全写那一行代码更容易/更明智。我知道我可以创建一个Task/Thread
对象并调用Start()
方法,但这需要更多的工作。我只是认为有了新的async/await功能,这类事情会更容易。
首先,你需要一个方法来同步完成非常昂贵的工作:
public void DoLotsOfWork<T>(T[] data, int start, int end)
{
Thread.Sleep(5000);//placeholder for real work
}
然后我们可以使用Task.Run
在一个线程池线程中启动该工作的多个实例。
List<Task> tasks = new List<Task>();
for(int i = 0; i < 4; i++)
{
tasks.Add(Task.Run(()=>DoLotsOfWork(data, start, end));
}
然后我们可以做一个非阻塞的等待,直到它们都完成:
await Task.WhenAll(tasks);