C# 在.NET4.5中使用async/await编写多线程方法
我有一个小问题 我承认,在.NET4.5之前,我很少使用多线程,但有了新的C# 在.NET4.5中使用async/await编写多线程方法,c#,.net,asynchronous,C#,.net,Asynchronous,我有一个小问题 我承认,在.NET4.5之前,我很少使用多线程,但有了新的async/await功能,我决定尝试一下。我开始尝试它,一切似乎都很好,但我无法在网络上的任何地方找到解决我“问题”的方法 因此,每个人都解释了如何将await与.Net平台新转换的方法(例如WriteAsync(),ReadAsync()等)结合使用,但如果我想将其用于我自己的方法呢?例如,假设我正在执行一个非常昂贵的计算,并希望我的4个内核都能处理它。我会有类似的东西: async Task DoLotsOfWork
async/await
功能,我决定尝试一下。我开始尝试它,一切似乎都很好,但我无法在网络上的任何地方找到解决我“问题”的方法
因此,每个人都解释了如何将await
与.Net平台新转换的方法(例如WriteAsync()
,ReadAsync()
等)结合使用,但如果我想将其用于我自己的方法呢?例如,假设我正在执行一个非常昂贵的计算,并希望我的4个内核都能处理它。我会有类似的东西:
async Task DoLotsOfWork<T>(T[] data, int start, int end)
{
//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
}
然后,我们可以进行非阻塞等待,直到完成所有操作:
await Task.WhenAll(tasks);
新的异步/等待模式不提供多线程。它只是为处理阻塞当前线程的操作提供了更干净的代码。关键字并不意味着“使用我所有的内核”。它们只是告诉编译器和运行时可以在sperate线程上执行操作。如果有4个操作可以同时运行,那么它们可能在4个不同的内核上运行。您想了解一下这一点,async await对多线程处理没有帮助。它甚至对单芯机器都有用。因此,换句话说,不要对多线程使用async/await。我现在明白了。谢谢。您完全可以将wait与多线程代码结合使用,您只需要一些机制来开始在另一个线程中运行代码,一旦您通过其他方式完成了这项工作,
async/wait
可以帮助您更有效地管理它们。或者,使用Parallel
类,这是为并行处理而设计的。@StephenCleary问题在于并行方法会阻塞,直到结果完成,因此您最终需要将并行。for
或Foreach
抛出到任务中。如果您当前处于(比如)UI上下文中,并且在任务完成之前无法阻塞,请运行。@Servy:True。但是,Parallel
的好处是,它将自动对工作进行分区,以充分利用可用的内核。正如您所说,您可以将其包装在Task.Run
中,以获取表示并行工作的Task
我有一个myFunction()返回一些值,我如何处理它?@codeln有一个列表
并将等待任务的结果存储在变量中。
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);