Fra*_*ayt 0 c# multithreading asynchronous
我知道对此有上百万个问题,我正在尝试他们的解决方案,但是它似乎并没有我期望的那样。
使用以下代码:
await Task.Run(() => { Thread.Sleep(5000); Console.WriteLine("I'm running after Thread.Sleep"); });
Console.WriteLine("I'm running after Task.Run");
Run Code Online (Sandbox Code Playgroud)
我得到的输出:
[ 5 seconds elapses ]
I'm running after Thread.Sleep
I'm running after Task.Run
Run Code Online (Sandbox Code Playgroud)
如果不使用,我将获得相同的输出 Task.Run
我想要的是输出:
I'm running after Task.Run
[ 5 seconds elapses ]
I'm running after Thread.Sleep
Run Code Online (Sandbox Code Playgroud)
在继续执行“父”线程的情况下,长时间运行的任务在“后台”执行的方式不影响“父”线程。
如前所述,您需要删除await。然而那把它变成一个发射后不管的任务,如果上面的代码恰好是在说一个控制台应用程序的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");
}
Run Code Online (Sandbox Code Playgroud)
坏: -没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
}
Run Code Online (Sandbox Code Playgroud)
因此I'm running after Thread.Sleep,即使您拥有,您也可能根本看不到Thread.Sleep()。(顺便说一句,您应该使用Task.Delay())。您可以使用来减轻它,Console.ReadKey()但可能会破坏目的。
即弃任务有其用途,可以合理地安全地用于其他类型的长期运行的应用程序中,例如WinForms,但人们通常不会在流程的入口点生成任务,因此任务通常无需任何操作即可完成提前终止流程。但是,通常在可能的情况下使用它是个好主意,await这样就不会在脚上开枪。
同样,您以某种顺序想要事物的要求表明了对async/await工作原理的误解。
使用时要记住的一件事await是您的代码等待对象。这些对象就像任何其他对象一样。具体来说,它们可以分配给局部变量或类变量。
所以,这段代码:
await Task.Run(() => { Thread.Sleep(5000); Console.WriteLine("I'm running after Thread.Sleep"); });
Console.WriteLine("I'm running after Task.Run");
Run Code Online (Sandbox Code Playgroud)
本质上与此代码相同:
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");
Run Code Online (Sandbox Code Playgroud)
换句话说:
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;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
160 次 |
| 最近记录: |