并行运行两个异步任务并在 .NET 4.5 中收集结果 [英] Run two async tasks in parallel and collect results in .NET 4.5
问题描述
我一直在尝试获得一些我认为使用 .NET 4.5 很简单的东西
I've been trying for a while to get something I thought would be simple working with .NET 4.5
我想同时启动两个长时间运行的任务并收集
结果是最好的 C# 4.5 (RTM) 方式
I want to fire off two long running tasks at same time and collect the
results in in the best C# 4.5 (RTM) way
以下有效,但我不喜欢它,因为:
The following works but I don't like it because:
- 我希望
Sleep
成为一个异步方法,以便它可以await
其他方法 - 它看起来很笨拙,
Task.Run()
- 我认为这根本没有使用任何新的语言功能!
- I want
Sleep
to be an async method so it canawait
other methods - It just looks clumsy with
Task.Run()
- I don't think this is even using any new language features at all!
工作代码:
public static void Go()
{
Console.WriteLine("Starting");
var task1 = Task.Run(() => Sleep(5000));
var task2 = Task.Run(() => Sleep(3000));
int totalSlept = task1.Result + task2.Result;
Console.WriteLine("Slept for a total of " + totalSlept + " ms");
}
private static int Sleep(int ms)
{
Console.WriteLine("Sleeping for " + ms);
Thread.Sleep(ms);
Console.WriteLine("Sleeping for " + ms + " FINISHED");
return ms;
}
非工作代码:
更新:这确实有效并且是正确的方法,唯一的问题是 Thread.Sleep
此代码不起作用,因为对 Sleep(5000)
的调用会立即启动任务运行,因此 Sleep(1000)
在完成之前不会运行.即使 Sleep
是 async
并且我没有使用 await
或过早调用 .Result
也是如此.
This code doesn't work because the call to Sleep(5000)
immediately starts the task running so Sleep(1000)
doesn't run until it has completed. This is true even though Sleep
is async
and I'm not using await
or calling .Result
too soon.
我想也许有一种方法可以通过调用 async
方法来获得非运行的 Task
,这样我就可以调用 Start()
在这两个任务上,但我不知道如何通过调用异步方法获得 Task
.
I thought maybe there is a way to get a non-running Task<T>
by calling an async
method so I could then call Start()
on the two tasks, but I can't figure out how to get a Task<T>
from calling an async method.
public static void Go()
{
Console.WriteLine("Starting");
var task1 = Sleep(5000); // blocks
var task2 = Sleep(1000);
int totalSlept = task1.Result + task2.Result;
Console.WriteLine("Slept for " + totalSlept + " ms");
}
private static async Task<int> Sleep(int ms)
{
Console.WriteLine("Sleeping for " + ms);
Thread.Sleep(ms);
return ms;
}
推荐答案
对于异步编程,您应该使用 Task.Delay 而不是 Sleep,然后使用 Task.WhenAll 来合并任务结果.这些任务将并行运行.
You should use Task.Delay instead of Sleep for async programming and then use Task.WhenAll to combine the task results. The tasks would run in parallel.
public class Program
{
static void Main(string[] args)
{
Go();
}
public static void Go()
{
GoAsync();
Console.ReadLine();
}
public static async void GoAsync()
{
Console.WriteLine("Starting");
var task1 = Sleep(5000);
var task2 = Sleep(3000);
int[] result = await Task.WhenAll(task1, task2);
Console.WriteLine("Slept for a total of " + result.Sum() + " ms");
}
private async static Task<int> Sleep(int ms)
{
Console.WriteLine("Sleeping for {0} at {1}", ms, Environment.TickCount);
await Task.Delay(ms);
Console.WriteLine("Sleeping for {0} finished at {1}", ms, Environment.TickCount);
return ms;
}
}
这篇关于并行运行两个异步任务并在 .NET 4.5 中收集结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!