理解概念
程序:占用資源的最小單元(相當於工作車間)
執行緒:排程運算的最小單元(相當於車間內的工人)
1.在使用winform窗體程式時,碰到耗時操作經常會導致窗體假死的情況;
那怎麼解決ui執行緒的假死問題呢?
可以使用非同步關鍵字async和await將阻塞的執行緒釋放出來,解決窗體在操作耗時函式的時候造成的假死問題。
非同步方法async可以修飾的返回值型別
void
task:表示返回的是乙個非同步任務
task:表示返回的是乙個返回值為t型別的非同步任務
await 等待的是什麼?
對應上述三種分別是void task 帶返回值的task
那task是什麼?
task表示非同步操作,可以理解為在另乙個執行緒執行任務,而不阻塞當前執行緒;
如何使用task?
呼叫start()方法後會在另乙個執行緒中立即執行dojob()函式中的內容,同時也會在主線程中往下執行messagebox.show函式,直到程式向下執行碰到t.wait或者t.result方法阻塞主線程,在這裡等待task的非同步任務處理完成再往下執行。
//方法一task t = new task(() => );
t.start();
messagebox.show(
"繼續幹活");
t.wait();
//阻塞主線程,等待任務完成
dojob()就是乙個返回值為string的普通函式;這裡使用建構函式建立的非同步任務,引數是乙個action委託,裡面放需要非同步執行的工作,注意需要執行t.start();才能執行任務;
//這裡使用工廠模式直接執行dojob任務方法二task tf = task.factory.startnew(() => );
messagebox.show(
"" +task.currentid);
tf.wait();
//阻塞主線程,等待任務完成
//使用task的run方法也是直接執行dojob任務方法三
task t = task.run(() => );
messagebox.show(
"繼續幹活");
string str = t.result;//
阻塞主線程,等待任務完成
由於上述的三種方法均使用了 .result 或者 .wait這兩個會阻塞主線程的方法,都會使得ui介面假死,因此就需要使用async和await關鍵字將執行緒釋放出來。
2.async和await關鍵字的使用情況:
主線程執行**:
task tas = dojobasync();//自己編寫的dojobasync非同步方法的**已經開始執行任務
this.button1.text = "
正在後台處理資料...";
messagebox.show(
"繼續幹活
");
//主線程在執行自己編寫的非同步方法
private taskdojobasync()
messagebox.show(
"非同步任務success");
return
"任務完成";
});return
t; }
tasktas = dojobasync();這段**後會立即向下執行這段**,而且dojobasync的工作是交給了另乙個執行緒進行處理;
this.button1.text = "正在後台處理資料...";如果需要拿到dojobasync的返回值怎麼辦呢?這裡的返回值是string
使用
string str = await tas;這裡使用await 關鍵字修飾,方法就必須使用async關鍵字修飾,否則就不是非同步方法。
因此方法體內使用了await關鍵字,那麼改方法就必須用async修飾,例如button click事件就必須要改寫為
private這樣的方式是不會阻止主線程,例如ui執行緒,不會陷入假死狀態。async
void button1_click(object
sender, eventargs e)
await 時是釋放執行緒,執行緒能去執行其它任務;.result 和 .wait 就是讓執行緒暫停,等待結果。
3.如何監控非同步任務的執行進度?
通過iprogress, progress只提供了乙個方法void report(t value),通過report方法把乙個t型別的值報告給iprogress,然後iprogress的實現類progress的建構函式接收型別為action的形參,通過這個委託讓進度顯示在ui介面中。
實際就是幹活的非同步方法必須要有乙個iprogress引數,然後通過report(t value)函式將進度反饋出去;
實現類怎麼構建呢?
progress通過建構函式生成,引數的型別是action的委託,這個委託可以把進度細節暴露到幹活的非同步方法之外,就實現了例如將進度寫到ui執行緒上。
**:
//主線程呼叫函式
private
async
task display()
%", percent);
});//執行緒池執行緒
//await task.run(() => doprocessing(progress));
await
dojobasync(progress);
console.writeline(
"");
console.writeline("結束
");}
//主函式直接在button click事件中呼叫即可。自己編寫的非同步方法
private task dojobasync(iprogressprogress)
thread.sleep(
5);//
模擬耗時操作
console.writeline("
anotherjob in thread:
" + thread.currentthread.managedthreadid + "
job exetimes:
" +i.tostring());
}messagebox.show(
"非同步任務success");
return
"任務完成";
});return
t; }
//end顯示進度
task ts =display();
await
ts;
C 非同步程式設計1
以下所有內容非本人自創,在學習c 過程中認為可能重要的寫到部落格中,以供查閱,文章 illustrated c 2012 fourth edition,author daniel m.solis 啟動程式時,系統會在記憶體中建立乙個新的 程序 程序是構成執行程式的資源集合。這些資源包括位址空間 檔案...
Linux下socket程式設計基礎1 初探
int socket int domain,int type,int protocol 呼叫socket 返回的描述字存在於協議族空間中,但是沒有乙個具體的位址,所以需要呼叫下面的bind 函式設定具體位址,否則當呼叫connect listen 時這個埠系統會隨機分配。int bind int s...
協程和非同步程式設計1
協程 coroutine 也可以被稱為微執行緒,是一種使用者態內的上下文切換技術。簡而言之,其實就是通過乙個執行緒實現 塊相互切換執行。例如 def func1 print 1 print 2 def func2 print 3 print 4 func1 func2 上述 是普通的函式定義和執行,...