是什么区别Task.WaitAll(),并Task.WhenAll()从异步CTP?您能提供一些示例代码来说明不同的用例吗?
我需要在控制台应用程序中运行多个异步任务,并在进一步处理之前等待它们全部完成.
那里有很多文章,但我读的越多越好.我已经阅读并理解了Task库的基本原理,但我显然错过了某处的链接.
我知道可以将任务链接起来,以便它们在另一个完成之后开始(这几乎是我读过的所有文章的场景),但我希望我的所有任务同时运行,我想知道一次他们都完成了.
对于这样的场景,最简单的实现是什么?
如果我不关心任务完成的顺序,只需要完成它们,我还应该使用await Task.WhenAll而不是多个await吗?例如,DoWork2低于优选的方法DoWork1(以及为什么?):
using System;
using System.Threading.Tasks;
namespace ConsoleApp
{
class Program
{
static async Task<string> DoTaskAsync(string name, int timeout)
{
var start = DateTime.Now;
Console.WriteLine("Enter {0}, {1}", name, timeout);
await Task.Delay(timeout);
Console.WriteLine("Exit {0}, {1}", name, (DateTime.Now - start).TotalMilliseconds);
return name;
}
static async Task DoWork1()
{
var t1 = DoTaskAsync("t1.1", 3000);
var t2 = DoTaskAsync("t1.2", 2000);
var t3 = DoTaskAsync("t1.3", 1000);
await t1; await t2; await t3;
Console.WriteLine("DoWork1 results: {0}", String.Join(", ", …Run Code Online (Sandbox Code Playgroud) .net c# parallel-processing task-parallel-library async-await
我已经尝试了一段时间来获得一些我认为可以简单地使用.NET 4.5的东西
我想同时启动两个长时间运行的任务,并
以最佳的C#4.5(RTM)方式收集结果
以下作品,但我不喜欢它,因为:
Sleep成为一个异步方法,所以它可以是await其他方法Task.Run()工作代码:
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;
}
Run Code Online (Sandbox Code Playgroud)
非工作代码:
更新:这实际上是有效的,并且是正确的方法,唯一的问题是 Thread.Sleep
此代码不起作用,因为调用Sleep(5000)立即启动任务运行,因此Sleep(1000) …
我正在阅读Stephen Cleary撰写的"C#Cookbook中的并发",我注意到以下技巧:
var completedTask = await Task.WhenAny(downloadTask, timeoutTask);
if (completedTask == timeoutTask)
return null;
return await downloadTask;
Run Code Online (Sandbox Code Playgroud)
downloadTask是对httpclient.GetStringAsync的调用,timeoutTask正在执行Task.Delay.
如果它没有超时,则downloadTask已经完成.为什么有必要做第二次等待而不是返回downloadTask.Result,因为任务已经完成了?
我使用控制台应用程序作为概念证明和获得异步返回值的新需求.
我发现我需要Task.WaitAll()在我的main方法中使用以避免需要异步"main()"方法,这是非法的.
我现在卡住试图弄清楚允许我使用泛型的重载,或者只返回我可以投射的对象,但是在Main()中.
.net c# console-application task-parallel-library async-await
据我所知,在调用task.Result中的async方法可能会导致死锁.我对这个问题有不同的看法,但......
我发现自己做了很多这种模式.我有几个返回相同类型结果的任务,所以我可以一次等待它们.我想分开处理结果,但是:
Task<int> t1 = m1Async();
Task<int> t2 = m2Async();
await Task.WhenAll(t1, t2);
Run Code Online (Sandbox Code Playgroud)
可以打电话Result到这里,因为我知道任务现在已经完成了吗?
int result1 = t1.Result;
int result2 = t2.Result;
Run Code Online (Sandbox Code Playgroud)
或者,我应该使用await静止...它似乎是多余的,可能有点丑陋取决于我需要如何处理结果:
int result1 = await t1;
int result2 = await t2;
Run Code Online (Sandbox Code Playgroud)
更新:有人将我的问题标记为此问题的副本:等待具有不同结果的多个任务.问题是不同的,这就是为什么我没有在我的搜索中找到它,尽管其中一个详细的答案确实可以回答.
注意:这是一个针对Asp.NetWeb 应用程序领域之外的问题。
一般来说,特别是在涉及库或控制台应用程序时,为了触发并忘记异步方法,只调用异步方法而不await使用它或使用它更好Task.Run吗?
基本上:
public static void Main(){
// Doing
_ = DoSomethingAsync();
// vs.
_ = Task.Run(DoSomethingAsync);
}
private static async Task DoSomethingAsync()
{
...
}
Run Code Online (Sandbox Code Playgroud) I want to use ToDictionary on a bunch of Task<MyObject> (see below). This works ok if I use TheTask.Result, but not await
This works:
Dictionary<CarId, Task<Model>> allModelTasks = carIds.ToDictionary(cId =>cId, cId=> GetModelForCar(cId));
await Task.WhenAll(allModelTasks.Values);
Dictionary<CarId, Model> allModels = allModelTasks.ToDictionary(mt => mt.Key, mt => mt.Value.Result);
Run Code Online (Sandbox Code Playgroud)
But if I replace last row with
Dictionary<CarId, Model> allModels = allModelTasks.ToDictionary(mt => mt.Key, async mt => await mt.Value);
Run Code Online (Sandbox Code Playgroud)
I get an error message that says "cant convert from Dict<CarId, Task<Model>> to Dict<CarId, Model>". …
我试图异步完成四个任务,当它们全部完成时,将它们附加到一个对象并返回它.
这是我的代码:
Task[] tasks = new Task[4];
tasks[0] = wtData.GetHFServiceData(wtTransfreeeId);
tasks[1] = wtData.GetTLServicesData(wtTransfreeeId);
tasks[2] = wtData.GetHMAServiceData(wtTransfreeeId);
tasks[3] = wtData.GetHSServiceData(wtTransfreeeId);
Task.WaitAll(tasks);
Run Code Online (Sandbox Code Playgroud)
问题是,由于Task[]没有Result方法,我必须定义类似的类型Task<MyType>[].但是,上述四个任务中的每一个都返回不同的类型.
在将所有任务添加到组合对象并返回之前,我怎么能等到所有任务完成?