我基于tutorial编写了示例代码。
我认为当运行TestAsync Task时,将打印“逻辑A”,然后使用“ await”关键字“ Logic C”进行打印。
但是它实际上就像同步方式一样运行,先打印“ Logic C”,然后打印“ Logic A”
class Program
{
static void Main(string[] args)
{
TestAll();
}
static async void TestAll()
{
var y = TestAsync();
// I want to do other jobs before task y finish
Console.WriteLine("Logic A");
int value = await y;
Console.ReadLine();
}
static Task<int> TestAsync()
{
for (int i = 0; i < 20000; i++)
;
Console.WriteLine("Logic C");
return Task.FromResult(0);
}
}
但是为什么先打印逻辑C然后再打印逻辑A?
谢谢答案,然后再问一个问题: 我希望“逻辑B”->“逻辑A”->“逻辑C”->“ 1”
但是它实际上只打印“逻辑B”->“逻辑A”并完成。
class Program
{
static void Main(string[] args)
{
TestAll();
}
static async void TestAll()
{
var y = TestAsync();
// I want to do other jobs before task y finish
Console.WriteLine("Logic A");
// delete this line will be correct, but I don't know why
int value = await y;
Console.WriteLine(value);
Console.ReadLine();
}
static async Task<int> TestAsync()
{
Console.WriteLine("Logic B");
await Task.Delay(100);
Console.WriteLine("Logic C");
return 1;
}
}
答案 0 :(得分:1)
如您所述,输出指示同步处理,因为它实际上是同步处理。
定义任务并不意味着异步处理。没有新的Task创建,您只将代码包装到Task,但没有创建新的Task。
如果要测试异步处理,则应修改方法:
private Task<int> TestAsync()
{
return Task.Run(() =>
{
for (int i = 0; i < 20000; i++)
;
Console.WriteLine("Logic C");
return Task.FromResult(0);
});
}
要回答您的另一个问题:
您没有所需的输出,因为您的Main方法没有等待异步操作完成。因此,当方法TestAll
中的执行转到int value = await y;
时,main方法将继续并正常完成。
更新您的Main方法以等待异步任务,您将获得所需的输出:
static void Main(string[] args)
{
TestAll().Wait();
}
但是请看synchronously waiting on asynchronous task
问题。它与上下文线程(UI线程,ASP上下文线程,...)相关,因此它对于控制台应用程序应该是安全的,但始终很了解what is behind
。