c 非同步程式設計 Task(一)

2022-07-09 00:00:18 字數 3053 閱讀 7739

thread執行緒是用來建立併發的一種低級別工具,它具有一些限制,尤其是:

task類可以很好的解決上述問題,它是乙個高階抽象:它代表了乙個併發操作(concurrent),該操作可能有thread支援,或不由thread支援。

開始乙個task最簡單的辦法就是使用task.run(.net4.5,4.0的時候是task.factory.startnew)傳入乙個action委託即可(例子task)

task.run(()=>);

task.status列舉狀態如下這裡就不詳細分析可以去官方文件查閱具體用法:

public enum taskstatus

if (task.status == taskstatus.rantocompletion)

呼叫task的wait方法會進行阻塞直到操作完成,相當於thread上的join方法。

task mytask = task.run(()=> 

);console.writeline(mytask.iscanceled);//false

mytask.wait();//阻塞主線程直到mytask執行完畢

console.writeline(mytask.iscanceled);//true

wait也可以讓你指定乙個超時時間和乙個取消令牌來提前結束等待。

針對長時間允許的任務或阻塞操作,你可以不用採用執行緒池

task task = task.factory.startnew(()=> 

,taskcreationoptions.longrunning);

如果同時執行多個long-running tasks(尤其是其中有出於阻塞狀態的),那麼效能將會受到很大影響,這是有比taskcreationoptions.longrunning更好的辦法:

task可以看做是乙個所謂的「未來/許諾」(future、promise),在它裡面包裹著乙個result,在稍後的時候就會變得可用。

在ctp版本的時候,task實際上叫做future

與thread不一樣,task可以很方便的傳播異常 如果你的task裡面丟擲了乙個未處理的異常,那麼該異常就會重新被丟擲給:

**如下:

task mytask = task.run(()=> );

trycatch (aggregateexception aex)

else

}

clr將異常包裹在aggregateexception裡,以便在並行程式設計場景中發揮很好的作用。

如果我們不想丟擲異常就想知道task有沒有發生故障,無需重新丟擲異常,通過task的isfaulted和iscanceled屬性也可以檢測出task是否發生了故障:

**如下:

taskmytask = task.run(() => 

);var awaiter = mytask.getawaiter();

awaiter.oncompleted(()=>

);

可以將continuation附加到已經結束的task上面,此時continuation將會被安排立即執行。

它對io-bound類工作比較理想

初始化乙個例項即可

它有乙個task屬性可返回乙個task

該task完全由taskcompletionsource物件控制

呼叫任意乙個方法都會給task發訊號:

這些方法只能呼叫一次,如果再次呼叫:

方法原始碼如下:

public class taskcompletionsource

public void setcanceled();

public void setexception(ienumerableexceptions);

public void setexception(exception exception);

public void setresult(tresult result);

public bool trysetcanceled();

public bool trysetcanceled(cancellationtoken cancellationtoken);

public bool trysetexception(ienumerableexceptions);

public bool trysetexception(exception exception);

public bool trysetresult(tresult result);

}

使用示例**:

/*

*code1

*/var tcs = new taskcompletionsource();

new thread(() =>

).start();

tasktask = tcs.task;

console.writeline(task.result);

/*code2

* 呼叫此方法相當於呼叫task.factory.startnew

* 並使用taskcreationoptions.longrunning選項來建立非執行緒池的執行緒

*/taskrun(funcfunc)

catch (exception ex)

}).start();

return tcs.task;

}

示例**:

Task非同步程式設計

task非同步程式設計中,可以實現在等待耗時任務的同時,執行不依賴於該耗時任務結果的其他同步任務,提高效率。1 task非同步程式設計方法簽名及返回值 a 簽名有async 修飾符 b 方法名以 async 結尾 良好的編碼習慣 根據約定,將 async 追加到具有 async 修飾符的方法名稱。如...

Task非同步程式設計,刨根到底

await 乙個非同步操作的時候,實際上編譯器會建立乙個狀態機,這個狀態機包含了呼叫者的上下文變數,狀態機使用yield迭代器實現,狀態機由clr排程,每次執行都會重新加入回佇列,直到task完成或異常結束 經常我們可以看到一些庫中使用taskcompletionsource來建立task,改變ta...

C 非同步程式設計(一)

概要 這裡記錄一下初始學習非同步程式設計。首先理解非同步這個操作 舉個例子來說吧。我們每個人可以做 很多事情 這裡用 事情一,事情二,事情三 我們自己如果需要完成這三件事情的話,那麼 基本上來說是要有順序的一件一件的完成,也就是 一心不能二用 的道理。那麼如果我們想提高 效率,快速的完成這三件事情呢...