C# async await 异步条件下的线程挂起(Sleep)方法

发布时间 2023-10-26 09:41:30作者: CollinsLi

async await 是 C# 5.0 中引入的异步编程简化方法,那如何使用这种方法进行异步时挂起线程(使某个线程等待一段时间)?

具体方法如下代码所示:

该代码第14行有一个循环,意图是每向Linux服务器发出一个命令(AsyncRunCommonCommand),然后等待一段设定的时间(AsyncWait)。

因为 async await 采用轮询机制,所以 await 方法执行完成之后才会向后执行,所以本解决方案在19行添加一个包含 Thread.Sleep 的 await 方法来实现上述功能。

 1 private async void bt_run_DE_Click(object sender, EventArgs e)
 2 {
 3     // 设置 每个任务的执行间隔
 4     int[] executionInterval = new int[4];
 5     executionInterval[0] = System.Convert.ToInt32(tb_EI_01.Text);
 6     executionInterval[1] = System.Convert.ToInt32(tb_EI_02.Text);
 7     executionInterval[2] = System.Convert.ToInt32(tb_EI_03.Text);
 8     executionInterval[3] = System.Convert.ToInt32(tb_EI_04.Text);
 9 
10     UpdateServersInformation(clb_targetServers_DE);
11     string Date = DateTime.Now.ToShortDateString().Replace("/", "-");
12     // remoteFileName 是运行脚本在服务器的路径,提取数据默认有两个脚本
13     int n = 0;
14     foreach (var item in remoteFileName)
15     {
16         string runWay = CommonClass.IdentificationExtension(item);
17         string commandText = "nohup "+ runWay+" " + item + " >& " + targetFilePath + "/" + localFile[localFile.Length - 1] + "/Log" + Date + " & ";
18         await Connection.AsyncRunCommonCommand(checkserversInformation, commandText, errorLogSaves);   // 正常需要执行的异步方法
19         await Connection.AsyncWait(executionInterval[n]);                                              // 在上个异步方法之后加入一个 async await 等待方法,该方法中包含 Thread.Sleep 方法
20         n = n + 1;
21     }
22 }

Connection 类中的AsyncWait方法如下所示:

 1 /// <summary>
 2 /// 异步 轮询等待 根据预设时间等待,直到命令完成
 3 /// </summary>
 4 /// <param name="time"></param>
 5 /// <returns></returns>
 6 public async Task<bool> AsyncWait(int time)
 7 {
 8     try
 9     {
10         var task = Task.Run(() =>
11         {
12             Console.WriteLine("The task has been sent and is waiting for completion, which is expected to take " + time.ToString()+ " minutes");
13             Thread.Sleep(60000* time);
14         });
15         await task; //异步等待,await本质上是一个可轮询状态机,不会阻塞线程
16                     //等task异步函数执行完毕后会再切到这里继续执行代码
17         Console.WriteLine("End of wait");
18         return true;
19     }
20     catch (Exception ex)
21     {
22         ESILLogManager.Error(ex.Message);
23         return false;
24         throw;
25     }
26 }

 

 

参考资料:

C# 关于异步等待async/await的学习理解 - WmW - 博客园 (cnblogs.com)

使用 Async 和 Await 的任务异步编程 (TAP) 模型 - C# | Microsoft Learn