异步编程新手求助:使用Thread.Sleep时Task.Run失效问题
异步编程疑问:Thread.Sleep导致Task.Run未正常执行?
我是异步编程新手,正在通过YouTube视频学习相关知识。发现当使用Thread.Sleep时,Task.Run似乎没有正常完成执行。
代码示例
class App { public static void Main(string[] args) { Console.WriteLine("app started"); AsTask(); Console.WriteLine("app Stopped"); } public static async void AsTask() { Console.WriteLine("outside await"); await Task.Run(() => { Console.WriteLine("Inside asyn fun"); Thread.Sleep(1); Console.Write("async Task Started"); Console.Write(" # Task Completed"); Console.WriteLine(); }); } }
问题现象
程序运行后,仅输出app started、outside await、Inside asyn fun,随后直接输出app Stopped并终止,Task.Run中后续的打印内容并未显示。
问题原因
async void的误用:AsTask方法声明为async void,这种形式仅适用于事件处理场景。普通方法调用async void方法时,调用方无法等待其异步操作完成——Main方法调用AsTask后会立即继续执行后续代码,不会等待Task.Run里的逻辑完成。- 进程提前终止:当Main方法执行完毕,整个应用进程会直接终止,此时
Task.Run中的操作哪怕只差最后一步(比如Thread.Sleep结束后的打印),也会被强制中断,无法完成。 Thread.Sleep的阻塞特性:Thread.Sleep会阻塞当前线程,虽然这里只阻塞1毫秒,但也给进程终止提供了时间窗口,导致后续代码来不及执行。异步编程中更推荐使用非阻塞的await Task.Delay(1)来替代。
修复方案
方案1:修正异步方法的返回类型,让Main等待异步操作完成
将async void改为async Task,同时让Main方法变为async Task并等待AsTask完成:
class App { public static async Task Main(string[] args) { Console.WriteLine("app started"); await AsTask(); Console.WriteLine("app Stopped"); } public static async Task AsTask() { Console.WriteLine("outside await"); await Task.Run(() => { Console.WriteLine("Inside asyn fun"); Thread.Sleep(1); Console.Write("async Task Started"); Console.Write(" # Task Completed"); Console.WriteLine(); }); } }
方案2:用非阻塞等待替代Thread.Sleep(更符合异步理念)
如果要避免线程阻塞,可以把Task.Run的委托改为async,用await Task.Delay替代Thread.Sleep:
await Task.Run(async () => { Console.WriteLine("Inside asyn fun"); await Task.Delay(1); Console.Write("async Task Started"); Console.Write(" # Task Completed"); Console.WriteLine(); });
内容的提问来源于stack exchange,提问作者Yugraaj Sandhu
相关产品推荐
相关产品推荐

