2010-10-18 42 views
1

我有一個由C#編寫的多線程應用程序,我的最大線程數爲256,並且此應用程序在Ip間隔(192.168.1.0 -192.168.205.255) 中獲得計算機的性能計數器,它工作正常並在一天內多次轉身。因爲我必須得到報告。中止非工作線程

但問題是有時一臺機器保持一個線程,永遠無法完成其工作,以便我的循環犯規轉...

還有什麼辦法來創建一個倒計時參數線程。當我在foreach中啓動線程?

foreach(Thread t in threads) 
{ 
    t.start(); -----> t.start(countdownParameter) etc.... 
} 

coundown參數是每個線程的最大生命週期。這意味着如果一個線程無法到達一臺機器,它必須中止。例如60秒..不是256臺機器,我的意思是256個線程......大約有5000個IP,其中600個是活着的。所以我使用256個線程來讀取它們的值。另一件事是循環。我的循環正在工作,而所有的客戶端完成它從一開始就開始。

+0

我不明白 - 你想要'countdownParameter'在這裏實現什麼? 「一臺機器保持線程」是什麼意思?這是如何阻止你的程序循環?發佈真實的代碼對於獲得有用的反饋會有很大的幫助。 – 2010-10-18 23:13:06

+0

你有256 *機器*?還是CPU的?還是實際的「線程」?或者是什麼? – Arafangion 2010-10-18 23:21:24

+0

@Arafangion - 我不敢問,但它看起來像一個線程,每個IP,乍一看 – 2010-10-18 23:22:55

回答

0

您無法爲線程執行指定超時。但是,您可以嘗試使用超時的每個線程Join,並在它不退出時放棄它。

foreach(Thread t in threads) 
{ 
    t.Start(); 
} 

TimeSpan timeOut = TimeSpan.FromSeconds(10); 
foreach(Thread t in threads) 
{ 
    if (!t.Join(timeOut)) 
    { 
     // Still not complete after 10 seconds, abort 
     t.Abort(); 
    } 
} 

當然也有更優雅的方式做到這一點,就像使用WaitHandle s的的WaitAll方法(注意:WaitAll在大多數實現時間限制爲64個手柄,並且在STA線程不工作,像UI線程)

+0

我試過這段代碼,但所有的線程都在等待完成之前創建的線程。這並不是有用的解決方案。 – Rapunzo 2010-10-21 13:32:39

0

你不應該從外部終止線程。 (Never kill a thread, make it commit suicide)。如果你不是非常小心的話,殺死一個線程很容易破壞一個appdomain的狀態。

您應該重寫線程中的網絡代碼,以便在達到時間限制時超時或使用異步網絡代碼。

+0

我試圖用計時器控制工作時間,但它阻止了我的操作。你提供什麼樣的解決方案? – Rapunzo 2010-10-19 07:38:46

+0

套接字API通常具有阻塞模式的TimeOut參數/屬性(例如.net Socked類上的SendTimeOut和ReceiveTimeOut),以及進入非阻塞(=異步)模式(Socket上的阻塞屬性)的方式。 – CodesInChaos 2010-10-19 07:44:43

+0

「殺死一個線程可能很容易破壞一個appdomain的狀態」也許這對操作系統線程是真的,但我懷疑中止一個託管線程會產生這種效果......我只是在中止的線程上引發一個ThreadAbortException。 – 2010-10-21 14:58:44

-1

您可以使用水木清華這樣的:

public static T Exec<T>(Func<t> F, int Timeout, out bool Completed) 
{ 
    T result = default(T); 
    Thread thread = new Thread(() => result = F()); 
    thread.Start(); 
    Completed = thread.Join(Timeout); 
    if(!Completed) thread.Abort(); 
    return result; 
} 
0

通常一個線程被卡在一個阻塞調用(當然,除非你有導致一個無限循環的錯誤)。您需要確定哪個呼叫被阻止,並「戳」它來解除阻止。這可能是因爲您的線程正在等待.NET BCL等待調用(WaitHandle.WaitOne等)之一,在這種情況下,您可以使用Thread.Interrupt來解鎖它。但是,就你而言,管理與遠程計算機的通信的API更可能是掛起的。有時,您可以簡單地關閉來自單獨線程的連接,並將解除掛起的方法(如Socket類的情況)。如果一切都失敗了,那麼你真的可能不得不回到最後調用Thread.Abort的方法。請記住,如果您中止某個線程,可能會損壞發起中止的應用程序域的狀態,甚至會損壞整個進程本身。 .NET 2.0中增加了很多規定,使得中止比以前更安全,但仍然存在一些風險。