日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

C#如何使用Task類解決線程的等待問題_C#教程

作者:郝偉博士 ? 更新時間: 2022-08-02 編程語言

使用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

欄目分類
最近更新