Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在.NET4.5中使用async/await编写多线程方法_C#_.net_Asynchronous - Fatal编程技术网

C# 在.NET4.5中使用async/await编写多线程方法

C# 在.NET4.5中使用async/await编写多线程方法,c#,.net,asynchronous,C#,.net,Asynchronous,我有一个小问题 我承认,在.NET4.5之前,我很少使用多线程,但有了新的async/await功能,我决定尝试一下。我开始尝试它,一切似乎都很好,但我无法在网络上的任何地方找到解决我“问题”的方法 因此,每个人都解释了如何将await与.Net平台新转换的方法(例如WriteAsync(),ReadAsync()等)结合使用,但如果我想将其用于我自己的方法呢?例如,假设我正在执行一个非常昂贵的计算,并希望我的4个内核都能处理它。我会有类似的东西: async Task DoLotsOfWork

我有一个小问题

我承认,在.NET4.5之前,我很少使用多线程,但有了新的
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);