我正试图用C#的async/await/continuewith来玩.我的目标是必须有两个并行运行的任务,尽管哪个任务按顺序执行一系列操作.为此,我计划有一个List<Task>代表并行运行的2个(或更多)任务,并且ContinueWith在每个Task
问题上使用我的问题是,在await taskList已经返回的情况下,似乎不执行继续回调.
为了总结,这里有一个例子来说明我期待发生的事情:
class Program
{
static public async Task Test()
{
System.Console.WriteLine("Enter Test");
await Task.Delay(100);
System.Console.WriteLine("Leave Test");
}
static void Main(string[] args)
{
Test().ContinueWith(
async (task) =>
{
System.Console.WriteLine("Enter callback");
await Task.Delay(1000);
System.Console.WriteLine("Leave callback");
},
TaskContinuationOptions.AttachedToParent).Wait();
Console.WriteLine("Done with test");
}
}
Run Code Online (Sandbox Code Playgroud)
预期的产出是
Enter Test
Leave Test
Enter callback
Leave callback
Done with test
Run Code Online (Sandbox Code Playgroud)
但是,输出是
Enter Test
Leave Test
Enter callback
Done with test
Run Code Online (Sandbox Code Playgroud)
有没有办法让ContinueWith被调用的Task 等待提供的函数在被认为完成之前完成?即..Wait将等待两个任务完成,原始任务和ContinueWith返回的任务
Nek*_*esh 39
当使用链接多个任务的ContinueWith方法,您的返回类型会Task<T>,而T是传递给委托/方法的返回类型ContinueWith.
由于异步委托的返回类型是a Task,你最终会得到a Task<Task>并最终等待异步委托返回Task第一个之后完成的委托await.
为了纠正这种行为,你需要使用返回的Task,嵌入你的Task<Task>.使用Unwrap扩展方法来提取它.
Ste*_*ary 26
当你在做async节目,你要努力,以取代ContinueWith用await,因为这样的:
class Program
{
static public async Task Test()
{
System.Console.WriteLine("Enter Test");
await Task.Delay(100);
System.Console.WriteLine("Leave Test");
}
static async Task MainAsync()
{
await Test();
System.Console.WriteLine("Enter callback");
await Task.Delay(1000);
System.Console.WriteLine("Leave callback");
}
static void Main(string[] args)
{
MainAsync().Wait();
Console.WriteLine("Done with test");
}
}
Run Code Online (Sandbox Code Playgroud)
使用的代码await更清晰,更易于维护.
此外,您不应将父/子任务用于async任务(例如,AttachedToParent).他们不是为了共同努力而设计的.
我想补充一下我的答案,以补充已经被接受的答案.根据您要执行的操作,通常可以避免异步委托和包装任务的额外复杂性.例如,您的代码可以像这样重新计算:
class Program
{
static async Task Test1()
{
System.Console.WriteLine("Enter Test");
await Task.Delay(100);
System.Console.WriteLine("Leave Test");
}
static async Task Test2()
{
System.Console.WriteLine("Enter callback");
await Task.Delay(1000);
System.Console.WriteLine("Leave callback");
}
static async Task Test()
{
await Test1(); // could do .ConfigureAwait(false) if continuation context doesn't matter
await Test2();
}
static void Main(string[] args)
{
Test().Wait();
Console.WriteLine("Done with test");
}
}
Run Code Online (Sandbox Code Playgroud)