2008-05-11 01:16
話又說回來,在上面的例子裡,我們想更好地區分開每個執行緒的輸出結果,讓其中乙個執行緒輸出大寫字母。我們傳入乙個狀態字到go中來完成整個任務,但我們不能使用threadstart委託,因為它不接受引數,所幸的是,.net framework定義了另乙個版本的委託叫做parameterizedthreadstart, 它可以接收乙個單獨的object型別引數:
public delegate void之前的例子看起來是這樣的:parameterizedthreadstart (object obj);
class threadtest
statichello!void go (object uppercase)
hello!
在整個例子中,編譯器自動推斷出parameterizedthreadstart委託,因為go方法接收乙個單獨的object引數,就像這樣寫:
thread t = newthread (new
parameterizedthreadstart (go));
t.start (true);parameterizedthreadstart的特性是在使用之前我們必需對我們想要的型別(這裡是bool)進行裝箱操作,並且它只能接收乙個引數。
乙個替代方案是使用乙個匿名方法呼叫乙個普通的方法如下:
staticvoid main() );
t.start();
}
static優點是目標方法(這裡是writetext),可以接收任意數量的引數,並且沒有裝箱操作。不過這需要將乙個外部變數放入到匿名方法中,向下面的一樣:void writetext (string text)
staticvoid main() );
text = "after";
t.start();
}
staticafter 匿名方法開啟了一種怪異的現象,當外部變數被後來的部分修改了值的時候,可能會透過外部變數進行無意的互動。有意的互動(通常通過字段)被認為是足夠了!一旦執行緒開始執行了,外部變數最好被處理成唯讀的——除非有人願意使用適當的鎖。void writetext (string text)
另一種較常見的方式是將物件例項的方法而不是靜態方法傳入到執行緒中,物件例項的屬性可以告訴執行緒要做什麼,如下列重寫了原來的例子:
class threadtest
void go()執行緒可以通過它的name屬性進行命名,這非產有利於除錯:可以用console.writeline列印出線程的名字,microsoft visual studio可以將執行緒的名字顯示在除錯工具欄的位置上。執行緒的名字可以在被任何時間設定——但只能設定一次,重新命名會引發異常。
程式的主線程也可以被命名,下面例子裡主線程通過currentthread命名:
class threadnaming
staticvoid go()
}hello from main
hello from worker
執行緒預設為前台執行緒,這意味著任何前台執行緒在執行都會保持程式存活。c#也支援後台執行緒,當所有前台執行緒結束後,它們不維持程式的存活。
改變執行緒從前台到後台不會以任何方式改變它在cpu協調程式中的優先順序和狀態。
執行緒的isbackground屬性控制它的前後臺狀態,如下例項:
class prioritytest );
if (args.length > 0) worker.isbackground= true;
worker.start();
}
}如果程式被呼叫的時候沒有任何引數,工作執行緒為前台執行緒,並且將等待readline語句來等待使用者的觸發回車,這期間,主線程退出,但是程式保持執行,因為乙個前台執行緒仍然活著。
另一方面如果有引數傳入main(),工作執行緒被賦值為後台執行緒,當主線程結束程式立刻退出,終止了readline。
後台執行緒終止的這種方式,使任何最後操作都被規避了,這種方式是不太合適的。好的方式是明確等待任何後台工作執行緒完成後再結束程式,可能用乙個timeout(大多用thread.join
)。如果因為某種原因某個工作執行緒無法完成,可以用試圖終止它的方式,如果失敗了,再拋棄執行緒,允許它與 與程序一起消亡。(記錄是乙個難題,但這個場景下是有意義的)
擁有乙個後台工作執行緒是有益的,最直接的理由是它當提到結束程式它總是可能有最後的發言權。交織以不會消亡的前台執行緒,保證程式的正常退出。拋棄乙個前台工作執行緒是尤為險惡的,尤其對windows forms程式,因為程式直到主線程結束時才退出(至少對使用者來說),但是它的程序仍然執行著。在windows任務管理器它將從應用程式欄消失不見,但卻可以在程序欄找到它。除非使用者找到並結束它,它將繼續消耗資源,並可能阻止乙個新的例項的執行從開始或影響它的特性。
對於程式失敗退出的普遍原因就是存在「被忘記」的前台執行緒。
執行緒的priority 屬性確定了執行緒相對於其它同一程序的活動的執行緒擁有多少執行時間,以下是級別:
enum只有多個執行緒同時為活動時,優先順序才有作用。threadpriority
設定乙個執行緒的優先順序為高一些,並不意味著它能執行實時的工作,因為它受限於程式的程序的級別。要執行實時的工作,必須提公升在system.diagnostics 命名空間下process的級別,像下面這樣:(我沒有告訴你如何做到這一點 )
process.getcurrentprocess().priorityclass = processpriorityclass.high;processpriorityclass.high 其實是乙個短暫缺口的過程中的最高優先級別:realtime。設定程序級別到realtime通知作業系統:你不想讓你的程序被搶占了。如果你的程式進入乙個偶然的死迴圈,可以預期,作業系統被鎖住了,除了關機沒有什麼可以拯救你了!基於此,high大體上被認為最高的有用程序級別。
和 mapviewoffile
)任何執行緒建立範圍內try/catch/finally塊,當執行緒開始執行便不再與其有任何關係。考慮下面的程式:
public static void main()
catch (exception ex)
static void go()
}
public static void main()
static void go()
catch (exception ex)從.net 2.0開始,任何執行緒內的未處理的異常都將導致整個程式關閉,這意味著忽略異常不再是乙個選項了。因此為了避免由未處理異常引起的程式崩潰,try/catch塊需要出現在每個執行緒進入的方法內,至少要在產品程式中應該如此。對於經常使用「全域性」異常處理的windows forms程式設計師來說,這可能有點麻煩,像下面這樣:
using system;
using system.threading;
using system.windows.forms;
staticclass
program
staticvoid handleerror (object sender, threadexceptioneventargs e)
}在產品程式中,明確地使用異常處理在所有執行緒進入的方法中是必要的,可以使用包裝類和幫助類來分解工作來完成任務,比如使用backgroundworker
類(在第三部分進行討論)。
c 將資料傳入ThreadStart中
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!2008 05 11 01 16 話又說回來,在上面的例子裡,我們想更好地區分開每個執行緒的輸出結果,讓其中乙個執行緒輸出大寫字母。我們傳入乙個狀態字到go中來完成整個任務,但我們不能使用threadstart委託,因為它不接受引數,所幸的是,ne...
將Kafka收到的資料傳入到redis中
首先得配置gateway中的config.properties 然後再看一下tbox中的properties main方法中 test中的config.properties test中 先啟動網管 gateway 再啟動終端 tbox 然後再執行kafkatest 啟動tbox 在啟動test 可以...
如何將c結構資料傳給lua
最近需要使用lua來讓策劃那些配置一些邏輯,於是調研了一下lua是如何實現這部分工作的,最終發現乙個通常的策劃是利用lightuserdata和metatable來協調解決這個問題。也即將資料 指標給lua,另外告訴它乙個如何操作這些資料的metamethods即可。請看下面的示例 typedef ...