【发布时间】:2019-04-12 02:07:42
【问题描述】:
好的,我想我几乎可以理解async / await 和多线程上的所有模糊问题了。我知道异步是关于任务的,多线程是关于工人的。所以你可以在同一个线程上运行不同的任务(this answer 很好地解释了它)。
所以我做了一个小程序来看看神奇的发生,我有点困惑:
public class Program
{
public static async Task Main(string[] args)
{
var task = ToastAsync();
Console.WriteLine($"[{Thread.CurrentThread.ManagedThreadId}] Cleaning the kitchen...");
await task;
Console.WriteLine($"[{Thread.CurrentThread.ManagedThreadId}] Take the toast");
}
public async static Task ToastAsync()
{
Console.WriteLine($"[{Thread.CurrentThread.ManagedThreadId}] Putting the toast");
Console.WriteLine($"[{Thread.CurrentThread.ManagedThreadId}] Setting a timer");
await Task.Delay(2000);
Console.WriteLine($"[{Thread.CurrentThread.ManagedThreadId}] Toast is ready");
}
}
在第一次运行这个程序之前,我希望它可以在单个线程上运行。就像我上面链接的答案一样,我希望这相当于“在吐司计时器运行时打扫厨房”。结果与它相矛盾:
[1] Putting the toast
[1] Setting a timer
[1] Cleaning the kitchen...
[4] Toast is ready
[4] Take the toast
上面的结果对我来说没有多大意义。到底发生了什么?似乎函数的一部分正在一个线程中执行,然后,当它到达await 点时,它会将执行处理到另一个线程......?我什至不知道这是可能的 D:
此外,我稍微改变了上面的例子。在主函数中,我使用了task.Wait(),而不是await task;。然后结果变了:
[1] Putting the toast
[1] Setting a timer
[1] Cleaning the kitchen...
[4] Toast is ready
[1] Take the toast
现在这看起来更像示例。就像烤面包上的计时器一样,不过是一个不同的“炊具”。但是为什么它与使用await 不同呢?有没有办法在一个线程中完全获取异步任务?我的意思是,在thread 1 上也有Toast is ready?
感谢异步!
【问题讨论】:
-
你真的需要它在一个线程上运行吗?任务是对线程的一种抽象。
-
另外,尽可能避免
.Wait(),它会阻塞当前线程直到任务完成,这违背了async的目的。
标签: c# multithreading asynchronous .net-core async-await