[英]Call async method after another async method is finished in C#
我想在步骤 1 完成后调用 step2 方法。 使用下面的代码,方法步骤 1 和步骤 2 并行执行。 当然,我需要它们是异步的,这样它们就不会阻止第 3 步的执行。
using System;
using System.Threading;
using System.Threading.Tasks;
namespace test
{
internal class Program
{
static void Main(string[] args)
{
async void step1()
{
await Task.Run(() =>
{
Thread.Sleep(2000);
Console.WriteLine("step 1");
});
}
async void step2()
{
await Task.Run(() =>
{
Thread.Sleep(5000);
Console.WriteLine("step 2");
});
}
void step3()
{
Console.WriteLine("step 3");
}
step1();
step2();
step3();
// the code below is not working but just and idea
// what I want to make. If it at all posible
// step1().step2()
// step3()
Console.ReadLine();
}
}
}
任何帮助将不胜感激。 请记住,我是 C# 的初学者!
编辑:
我知道即使使用这段代码我也可以获得最终结果。
void step1() { Thread.Sleep(2000); Console.WriteLine("step 1"); } void step2() { Thread.Sleep(5000); Console.WriteLine("step 2"); } void step3() { Console.WriteLine("step 3"); } step3(); step1(); step2();
即使根本没有异步/等待。
这个问题的重点是做一个小的概念验证应用程序,即使代码是这样设置的:
step1(); step2(); step3();
最后设置 step3() 的地方将首先执行,因为没有延迟,而且 step2() 必须等待 step1() 完成。
这完全有可能在 C# 中使用异步/等待。我认为这可以通过 javascript 中的承诺来完成。
如果您将Main
方法(以及step1
和step2
)更改为async Task
而不是void
(或async void
),您将能够等待您的方法。
static async Task Main(string[] args)
{
async Task step1()
{
await Task.Run(() =>
{
Thread.Sleep(2000);
Console.WriteLine("step 1");
});
}
async Task step2()
{
await Task.Run(() =>
{
Thread.Sleep(5000);
Console.WriteLine("step 2");
});
}
void step3()
{
Console.WriteLine("step 3");
}
step3(); // You can put step3 here if you want it to run before step1 and step2.
await step1();
await step2();
Console.ReadLine();
}
我建议您查看这篇 Microsoft 文章,以更好地了解async Task
与async void
。
对于异步方法的工作原理可能存在误解。 所有异步方法开始同步运行,就像任何其他方法一样。 当await
作用于未完成的Task
时,奇迹就会发生。 此时,该方法向调用方法返回一个新的不完整Task
(或者如果它是void
返回任何内容,这就是为什么您应该避免使用async void
)。
因此,如果您首先调用step1()
,那么step1()
将首先开始执行 - 没有办法解决这个问题。 但是当step1()
命中await Task.Run(...)
时,它返回并且Main
方法继续执行。 到那时,您可以决定要做什么。 你想等到step1()
完成还是 go 做其他事情?
如果需要,代码如下所示:
step1()
首先开始执行。step2()
仅在step1()
完成后才开始。step3()
在step1()
开始后尽快执行,但不等待step1()
完成。static async Task Main(string[] args)
{
async Task step1()
{
Console.WriteLine("step 1 starting");
await Task.Run(() =>
{
Thread.Sleep(2000);
Console.WriteLine("step 1 done");
});
}
async Task step2()
{
Console.WriteLine("step 2 starting");
await Task.Run(() =>
{
Thread.Sleep(5000);
Console.WriteLine("step 2 done");
});
}
void step3()
{
Console.WriteLine("step 3");
}
var step1task = step1();
step3();
await step1task;
await step2();
Console.ReadLine();
}
output 是:
step 1 starting
step 3
step 1 done
step 2 starting
step 2 done
如果您希望step3()
在step1()
甚至开始执行之前执行,那么您需要先调用step3()
- 没有办法绕过它。
如果约束是
step1();
step2();
step3();
那么答案是这是不可能的。
除非您可以控制步骤中的代码,并执行线程信号以防止步骤 2 在步骤 1 结束之前开始。 阅读有关 ManualResetEvent 的信息。
static void Main(string[] args)
{
var mre = new ManualResetEvent(false);
void step1()
{
Task.Run(() =>
{
Thread.Sleep(1000);
Console.WriteLine("step 1");
mre.Set();
});
}
void step2()
{
Task.Run(() =>
{
mre.WaitOne();
Console.WriteLine("step 2");
});
}
void step3()
{
Console.WriteLine("step 3");
}
step1();
step2();
step3();
Console.ReadLine();
}
放弃异步,这不是你想的那样。 使用 ContinueWith
Task step1()
{
return Task.Run(() =>
{
Thread.Sleep(2000);
Console.WriteLine("step 1");
});
}
Task step2()
{
return Task.Run(() =>
{
Thread.Sleep(5000);
Console.WriteLine("step 2");
});
}
void step3()
{
Console.WriteLine("step 3");
}
var task = step1()
.ContinueWith(x => step2());
step3();
task.Wait();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.