我知道对此有上百万个问题,我正在尝试他们的解决方案,但它似乎并没有我期望的那样。
使用以下代码:
await Task.Run(() => { Thread.Sleep(5000); Console.WriteLine("I'm running after Thread.Sleep"); });
Console.WriteLine("I'm running after Task.Run");
我得到输出:
[ 5 seconds elapses ]
I'm running after Thread.Sleep
I'm running after Task.Run
与不使用Task.Run
时得到的输出是相同的
我想要的是输出:
I'm running after Task.Run
[ 5 seconds elapses ]
I'm running after Thread.Sleep
“父”线程的执行继续进行,并且长时间运行的任务在“后台”执行的方式不会影响“父”线程。
答案 0 :(得分:4)
如上所述,您需要删除await
。 但是将其转换为 fire-and-forget 任务,如果上述代码恰好位于控制台应用程序的Main
中,则您的过程可以在任务完成之前终止。
好:
// C# 7
static async void Main(string[] args) // <--- note `async` signature
{
await Task.Run(() => { Thread.Sleep(5000); Console.WriteLine("I'm running
after Thread.Sleep"); });
Console.WriteLine("I'm running after Task.Run");
}
错误:-未await
完成的即发即弃任务
static void Main(string[] args)
{
Task.Run(() => { Thread.Sleep(5000); Console.WriteLine("Spider Man: I don't wan't to go!"); }); // POOF!!
Console.WriteLine("I'm running after Task.Run");
// sorry Spidy, you're dead
}
因此,即使您拥有I'm running after Thread.Sleep
,也可能根本看不到Thread.Sleep()
。 (顺便说一句,您应该使用Task.Delay()
)。您可以使用Console.ReadKey()
减轻它的负担,但这可能无法达到目的。
“一劳永逸”任务有其用途,可以合理地在其他类型的长期运行应用中安全使用,例如WinForms,但人们通常不会在流程的条目中生成任务因此任务通常可以完成,而不会被流程提前终止。但是,通常在可能的地方使用await
是个好主意,这样就不会在脚上开枪。
此外,您以某种顺序想要事物的要求也显示出对async/await
的工作方式的误解。
答案 1 :(得分:1)
使用await
时要记住的一件事是您的代码正在等待对象。这些对象与其他任何对象一样。具体来说,可以将它们分配给局部变量或类变量。
因此,此代码:
await Task.Run(() => { Thread.Sleep(5000); Console.WriteLine("I'm running after Thread.Sleep"); });
Console.WriteLine("I'm running after Task.Run");
基本上与此代码相同:
var task = Task.Run(() => { Thread.Sleep(5000); Console.WriteLine("I'm running after Thread.Sleep"); });
await task;
Console.WriteLine("I'm running after Task.Run");
换句话说:
await
)等待该任务完成。"I'm running after Task.Run"
。所以预期的输出。
我想要的是输出:
我正在执行Task.Run
[5秒钟过去了]
我正在追赶Thread.Sleep
在这种情况下,请启动在后台线程上运行的任务,但要等到以后再await
:
var task = Task.Run(() => { Thread.Sleep(5000); Console.WriteLine("I'm running after Thread.Sleep"); });
Console.WriteLine("I'm running after Task.Run");
await task;
答案 2 :(得分:-1)
如果要异步运行,则应删除命令
static void Main(string[] args)
{
Task.Run(() => { Thread.Sleep(5000); Console.WriteLine(DateTime.Now + " => I'm running after Thread.Sleep"); });
Console.WriteLine(DateTime.Now + " => I'm running after Task.Run");
while (true)
{
Thread.Sleep(500);
}
}
输出
28/05/2019 09:49:58 => I'm running after Task.Run
28/05/2019 09:50:03 => I'm running after Thread.Sleep