在.net 4.5中使用async/await编写多线程方法



我有一个小查询。

我承认在。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);

最新更新