C# 异步和等待不起作用
我正在尝试学习.NET4.5的异步和等待特性C# 异步和等待不起作用,c#,.net,asynchronous,async-await,C#,.net,Asynchronous,Async Await,我正在尝试学习.NET4.5的异步和等待特性 static async void Method() { await Task.Run(new Action(DoSomeProcess)); Console.WriteLine("All Methods have been executed"); } static void DoSomeProcess() { System.Threading.Thread.S
static async void Method()
{
await Task.Run(new Action(DoSomeProcess));
Console.WriteLine("All Methods have been executed");
}
static void DoSomeProcess()
{
System.Threading.Thread.Sleep(3000);
}
static void Main(string[] args)
{
Method();
//Console.WriteLine("Method Started");
Console.ReadKey();
}
这段代码不会在控制台上给我任何结果。我不明白为什么。我的意思是任务不应该是没有阻塞的线程。但是,如果我在main方法中取消对Console.WriteLine()的注释,一切似乎都正常
有人能告诉我这里发生了什么吗?对于异步/等待模式,一些事情与之前的线程不同
System.Threading.Thread.Sleep
因为这仍然是阻塞,不能与异步一起工作。
改为使用Task.Delay
异步void
方法。基本上,async void只适用于无法返回某些内容的事件处理程序。所有其他异步方法应返回Task
或Task
static async Task Method()
{
await DoSomeProcess();
Console.WriteLine("All Methods have been executed");
}
static async Task DoSomeProcess()
{
await Task.Delay(3000);
}
现在改变你的主要方法,因为这应该是你开始任务的地方
Task.Run(() => Method()).Wait();
//Console.WriteLine("Method Started");
Console.ReadKey();
学习如何正确使用
async
和wait
关键字有一个很小的学习曲线
问题是没有人在等待谁,还有一些其他细节,如SyncronizationContext
和任务
:
你应该查看一些文章:
要在Console中使用async和await关键字,您需要额外的代码:
或
或
我通常采用这种方法:
static void Main(string[] args)
{
Console.WriteLine("HELLO WORLD");
var t1 = Task.Factory.StartNew(new Func<Task>(async () => await Method()))
.Unwrap();
Console.WriteLine("STARTED");
t1.Wait();
Console.WriteLine("COMPLETED");
Console.ReadKey();
}
static async Task Method()
{
// this method is perfectly safe to use async / await keywords
Console.WriteLine("BEFORE DELAY");
await Task.Delay(1000);
Console.WriteLine("AFTER DELAY");
}
static void Main(字符串[]args)
{
Console.WriteLine(“你好世界”);
var t1=Task.Factory.StartNew(新函数(异步()=>await方法())
.Unwrap();
Console.WriteLine(“已启动”);
t1.等待();
控制台。写入线(“已完成”);
Console.ReadKey();
}
静态异步任务方法()
{
//此方法使用async/await关键字是完全安全的
控制台写入线(“延迟前”);
等待任务。延迟(1000);
控制台写入线(“延迟后”);
}
这对我来说就像预期的那样,它打印出所有方法在3秒钟后都被执行到控制台。除非我在main中取消对Console.WriteLine的注释,否则我在3秒钟后在控制台上什么也得不到。通常,您应该避免使用async void
方法,因为无法等待它们的完成。但是在这个特定的例子中,您的代码可以正常工作(除非在睡眠完成之前按Enter键)。取消注释也可以正常工作:)我在方法()中的WriteLine上插入了一个断点。线程似乎到达了那里,但由于某种原因,控制台上没有显示。为什么会发生这种情况为什么需要调用Task.Run
?Hero,Task.Run(()=>Method()).Wait();工作完美你为什么要创建另一个任务?Method
返回的任务不够好吗?我需要封装一个任务,以便使用它的SynchronizationContext,如果我不这样做,根据当前的上下文,“Completed”文本将能够在“After Delay”之前显示@Servy抱歉,这是真的,我也不想让人们混淆事情,但在使用任务时这是一个“技巧”“打开“方法然后发生的所有事情都尊重async/await关键字。@J.Lennon,在控制台应用程序上没有SynchronizationContext
。即使打开了,SynchronizationContext
使用的是编译器在async
/wait
@J.Lennon时生成的状态机Unwrap
需要向右滚动才能看到。因为它是唯一没有显示在屏幕上的东西,所以我没有注意到它。也就是说,您的async
匿名方法仍然毫无意义。如果您只编写t1=Method(),代码将更加简单、可读且有效代码>