網站首頁 編程語言 正文
使用Task類解決線程的等待問題
在任何的編程語言中,面對耗時任務時,我們都會有這樣的需求:讓任務執行一定時間,主任務進行等待,如果到時仍然完成不了,那么就不再等待。
比如一個常見的應用就是連接遠程數據庫,如果由于網絡問題連接不上,那么只等待指定時間如3秒,然后就不再等待。
這樣的代碼如果自己寫類來實現的話并不困難,然而實際上C#已經內置了Task類用于解決此問題。
Task類
Task是C#中專門用于接收任務的類,通過構造函數接收任務,使用start()方法啟動。當任務啟動以后,可以使用Task.WaitAll(Task[] tasks, int timeout) 等待所有任務完成后或時間到 timeout ms后再繼續。
注:由于Task的構造函數接受的是Action委托,所以是沒有返回值的。
用法
Task核心功能是代理一個方法,然后在啟動,主線程可以指定等待時間,具體如以下代碼所示。
// 1. 初始化任務
var t1 = new Task(() => {
?? ??? ?Thread.Sleep(2000);
?? ??? ?Console.WriteLine("Hello");
?? ?}); ?
// 2. 啟動任務?? ?
t1.start();
// 3. 指定等等時間,單位為毫秒
Task.WaitAll(new Task[] { t1 }, 3000); ?
示例
在本示例中,我們啟動了一個簡單的任務t1,會暫時2秒然后輸出字符串“Hello”,然后主線程等待3000毫秒,代碼如下所示:
void Test1()
{
?? ?//定義一個任務,等待2秒后輸出Hello?
?? ?var t1 = new Task(() => {
?? ??? ?Thread.Sleep(2000);
?? ??? ?Console.WriteLine("Hello");
?? ?}); ?
?
??? ?// 以多線程方式啟動任務,t1和當前線程是兩個線程
?? ?t1.Start();?
?? ?Console.WriteLine("t1 started.");
?? ?//等待所有任務結束(這里只有t1),程序會卡在這里。等待的時間為 3000 毫秒
?? ?Console.WriteLine("waiting...");
?? ?Task.WaitAll(new Task[] { t1 }, 3000); ?
?? ?Console.WriteLine("stop waiting.")
?? ?// 判斷t1任務是否完成
?? ?if (!t1.IsCompleted)
?? ??? ?Console.WriteLine("Running...");
?? ?Console.WriteLine("Task done.");
}?? ??? ??? ?
void print(string msg)
{
?? ?Console.WriteLine($"{DateTime.Now:HH:mm:ss.ffff} {msg}");
}
程序運行后輸出以下結果:
14:51:54.2233 t1 started.
14:51:54.2457 waiting...
14:51:56.2456 Hello
14:51:56.2456 stop waiting.
14:51:56.2456 Task done.
可以看到,程序在等待后約2000毫秒,任務t1執行完成,輸出 Hello,但是由于我們設置的等待時間是3000毫秒,所以主線程仍然在等待中。在經過了約3000毫秒后,程序停止等待,繼續執行。在繼續執行時,由于t1已經執行完成,所以沒有輸出繼續執行的相關信息。
下面我們將上面的等待時間由3000毫秒改為1000毫秒,那么在執行以后結果如下所示:
14:48:36.9624 t1 started.
14:48:36.9848 waiting...
14:48:37.9755 stop waiting.
14:48:37.9755 t1 still running...
14:48:37.9755 Task done.
14:48:38.9860 Hello
由以上結果可見,程序在等待了約1000毫秒后,由于等待時間已經到了,就繼續向前執行,此時 t1 并沒有執行完成,所以會輸出 “t1 still running…”。等主線程執行完以后,t1 最終執行完成,輸出了Hello。
小結
由以上示例可見,Task能夠很方便的啟動一個任務,主線程也可以決定等待時間。
不過這里還有三點需要注意一下:
1)Task沒有返回值;
2)主線程不能中止Task;
3)計時精度不高,有一定的誤差。
基于以上問題,我們可以知道Task類合適用在一些對控制和計時精度要求不高的場合。
C#代碼執行中等待10秒
//等待10秒
DateTime dt1 = DateTime.Now;
while ((DateTime.Now - dt1).TotalMilliseconds < 10000)
{
continue;
};
原文鏈接:https://haolaoshi.blog.csdn.net/article/details/107180300
相關推薦
- 2022-08-31 SQL注入報錯注入函數圖文詳解_數據庫其它
- 2022-08-05 C#?GDI+實現時鐘表盤_C#教程
- 2022-06-26 Windows?Server?2012?R2安裝與基本配置詳細步驟_win服務器
- 2023-03-27 詳解如何在React中優雅的使用addEventListener_React
- 2023-07-14 431報錯和解決方法
- 2022-08-03 GoFrame框架garray并發安全數組使用開箱體驗_Golang
- 2022-04-17 使用docker-compose構建鏡像并構建服務時,想為構建的鏡像統一加上指定版本
- 2023-11-11 flask python 設置定時任務 flask 周期性執行任務方案
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支