为什么我在运行以下程序时在控制台中看不到任何内容?
当我取消注释这两行时,我会看到两条完成消息(为什么不只是"Foo Done!"
?)
class Program
{
static void Main(string[] args)
{
//var foo = new Foo();
var bar = new Bar();
}
private class Foo
{
public Foo()
{
DoWork();
}
private void DoWork()
{
Console.WriteLine("Foo Done!");
}
}
private class Bar
{
public Bar()
{
DoWorkAsync();
}
private async void DoWorkAsync()
{
await Task.Run(() => Console.WriteLine("Bar Done!"));
}
}
}
答案 0 :(得分:1)
这很简单:
添加
Console.ReadLine(); // waits for a key to be pressed on form
之后
var bar = new Bar();
等待用户操作。
答案 1 :(得分:1)
正如@Servy所指出的那样,这是一种非确定性的行为 - 我无法在我的机器上得到它没有打印,你无法得到它打印你的。
为什么它是非确定性的?这是因为:
这意味着您运行的任务及其继续(通过异步等待程序注册)都将在后台线程上运行,因此如果主线程(整个应用程序)在能够打印之前结束,则您赢得了'什么都看不见。
为什么在第二种情况下会为您打印?再次 - 因为它是一种非确定性行为,取决于任务调度和操作系统状态。
答案 2 :(得分:1)
但是当我取消注释这两行时,为什么我会看到这两条消息?为什么不只是“Foo完成!” ?
您的代码在Main
终止和线程池线程上的委托执行之间存在竞争条件,因此您的结果将是非确定性的。如果Task
足够快地执行委托,您将看到两者。不能保证一个人会先完成另一个。
运行你的代码足够多次,你最终可能只会抓住“Foo Done”。
答案 3 :(得分:1)
当您同时取消注释时,您可能会幸运地看到"Bar Done!"
。
因为您正在运行Bar
异步,所以主线程可能在它有机会写入控制台之前完成。添加Foo
可能会减慢主线程的速度,使写入工作。
尝试等待DoWorkAsync
private class Bar {
public Bar() {
DoWorkAsync().Wait();
}
private async Task DoWorkAsync()
{
return await Task.Run(() => Console.WriteLine("Bar Done!"));
}
}