想请教下为什么在控制台main方法中运行这段代码没有任何输出?
而只能把Wait()注释取消才行。
朋友开发环境是vs 没问题 我是用rider 打印不出任何内容
```c#
public async static Task<string> Get0()
{
var t = Task<string>
.Run(
() =>
{
Console.WriteLine("Get00000000000");
return "999";
}
);
//t.Wait();
Console.WriteLine(await t);
Console.WriteLine("1111111111111");
return "";
```
加入
t.ConfigureAwait(false).GetAwaiter().GetResult(); //这句效果和wait一样,都是同步。不过是忽略上下文,避免同步死锁
如果这句能通过,表明rider 执行输出的机制和vs不一样,他可能是一个“IO重定向”,然后碰上wait同步产生了死锁状态
参考GPT和自己的思路:这是因为你漏掉了使用async
关键词的异步方法调用必须使用await
操作符。在这种情况下,如果您取消注释掉Wait()
,那么代码中的异步任务可能无法完成。await
关键字提供了一种表示异步任务完成的方式,只有当异步任务完成后才会运行后续代码。如果您不需要等待Task
完成,请确保可发生这种情况。
在异步编程的规范中,async修饰的方法,仅仅表示这个方法在内部有可能采用异步的方式执行,CPU在执行这个方法时,会放到一个新的线程中执行。
那这个方法,最终是否采用异步执行,不决定于是否用await方式调用这个方法,而决定于这个方法内部,是否有await方式的调用。
看代码,很容易理解:
private static async Task func1()
{
Console.WriteLine("Func1 proccess - start");
Thread.Sleep(1000);
Console.WriteLine("Func1 proccess - end");
}
这个方法,因为方法内部没有await调用,所以这个方法永远会以同步方式执行,不管你调用这个方法时,有没有await。
而下面这个代码:
private static async Task func1()
{
Console.WriteLine("Func1 proccess - start");
await Task.Run(() => Thread.Sleep(1000));
Console.WriteLine("Func1 proccess - end");
}
因为这个方法里有await调用,所以这个方法不管你以什么方式调用,有没有await,都是异步执行的。
看代码:
static async Task Main(string[] args)
{
Console.WriteLine("Async proccess - start");
Console.WriteLine("Async proccess - enter Func1");
func1();
Console.WriteLine("Async proccess - out Func1");
Console.WriteLine("Async proccess - enter Func2");
func2();
Console.WriteLine("Async proccess - out Func2");
Console.WriteLine("Async proccess - enter Func3");
func3();
Console.WriteLine("Async proccess - out Func3");
Console.WriteLine("Async proccess - done");
Console.WriteLine("Main proccess - done");
Console.ReadKey();
}
private static async Task func1()
{
Console.WriteLine("Func1 proccess - start");
await Task.Run(() => Thread.Sleep(1000));
Console.WriteLine("Func1 proccess - end");
}
private static async Task func2()
{
Console.WriteLine("Func2 proccess - start");
await Task.Run(() => Thread.Sleep(3000));
Console.WriteLine("Func2 proccess - end");
}
private static async Task func3()
{
Console.WriteLine("Func3 proccess - start");
await Task.Run(() => Thread.Sleep(5000));
Console.WriteLine("Func3 proccess - end");
}
输出结果:.
Async proccess - start
Async proccess - enter Func1
Func1 proccess - start
Async proccess - out Func1
Async proccess - enter Func2
Func2 proccess - start
Async proccess - out Func2
Async proccess - enter Func3
Func3 proccess - start
Async proccess - out Func3
Async proccess - done
Main proccess - done
Func1 proccess - end
Func2 proccess - end
Func3 proccess - end
结果中,在长时间运行Thread.Sleep的时候,跳出去往下执行了,是异步。
又有问题来了:不是说异步调用要用await吗?
我们把await加到调用方法的前边,试一下:
static async Task Main(string[] args)
{
Console.WriteLine("Async proccess - start");
Console.WriteLine("Async proccess - enter Func1");
await func1();
Console.WriteLine("Async proccess - out Func1");
Console.WriteLine("Async proccess - enter Func2");
await func2();
Console.WriteLine("Async proccess - out Func2");
Console.WriteLine("Async proccess - enter Func3");
await func3();
Console.WriteLine("Async proccess - out Func3");
Console.WriteLine("Async proccess - done");
Console.WriteLine("Main proccess - done");
Console.ReadKey();
}
跑一下结果:
Async proccess - start
Async proccess - enter Func1
Func1 proccess - start
Func1 proccess - end
Async proccess - out Func1
Async proccess - enter Func2
Func2 proccess - start
Func2 proccess - end
Async proccess - out Func2
Async proccess - enter Func3
Func3 proccess - start
Func3 proccess - end
Async proccess - out Func3
Async proccess - done
Main proccess - done
嗯?怎么又像是同步了?
对,这是第二个容易错误的理解:await是什么意思?
任务分配给变量 t, t.Wait()被注释掉了,所以它不会被执行。