13

我有一个小问题。

我承认在 .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 功能,这种事情会更容易。

4

1 回答 1

18

因此,首先您需要一种同步完成非常昂贵的工作的方法:

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);
于 2013-03-07T15:02:27.600 回答