2012-05-31 18 views
1

我在結束一組動態創建的線程時遇到了一些麻煩。我需要在任何特定點結束所有這些的原因是,我可以刷新表單的某些部分並創建新表單。這裏有一個簡單的場景來展示我的線程發生了什麼。你如何加入/中止一組動態創建的線程?

多個線程被創建動態地基於就地某些變量:

for (int i = 0; i <= mDevices.Count; i++) 
     { 
      ThreadStart workerThread = delegate { pollDevices(mDevices[i - 2], this); }; 
      new Thread(workerThread).Start(); 
     } 

    public void pollDevices(IDeviceInterface device, DeviceManager mainUI) 
    { 
     System.Timers.Timer timer = null; 
     if (timer == null) 
     { 

      timer = new System.Timers.Timer(1000); 
      timer.Elapsed += delegate(object sender, ElapsedEventArgs e) { timerElapsed(sender, e, device, mainUI); }; 

     } 
     timer.Enabled = true; 

public void timerElapsed(object sender, ElapsedEventArgs e, IDeviceInterface device, DeviceManager mainUI) 
    { 


     device.connect(device, this); 
     //wait till thread finishes and destroy 
     Thread.CurrentThread.Abort(); 
    } 

這些線程然後工作過計時器,和PROC一個事件,它處理UI更新和這樣。然而,當我嘗試刷新用戶界面(例如,如果有更多的數據庫中的條目需要考慮)我從窗體上刪除按鈕(這些都分配給一個線程),如果一個線程仍然運行,我呼籲刷新我需要以這種方式停止所有當前線程。

所以我的問題是,我如何中止這組線程之前我刷新我的用戶界面?

回答

2

你有幾個問題。

  • 你是closing over a loop variable
  • 您正在爲啓動計時器創建一個線程...爲什麼不只是在主線程中啓動計時器?
  • 您的計時器實例未生根,因此有可能它在您完成之前有資格進行垃圾回收。
  • System.Timers.Timer事件處理程序將在ThreadPool線程上執行(至少在這種情況下),所以試圖中止這些線程之一不會很好。

在我們能夠回答您的主要問題之前,您有足夠的問題想要做一些重大的重組。一個額外的技巧,儘管...不要嘗試訪問或操作除主UI線程以外的任何UI元素。

+0

猜想我需要重新思考某些事情之後,我繼續前進......有什麼指針/我應該首先查找的東西? –

0

爲什麼在線程proc中使用定時器?

ManualResetEvent exit = new ManualResetEvent(false); 
for (int i = 0; i <= mDevices.Count; i++) 
    { 
     ThreadStart workerThread = delegate { pollDevices(mDevices[i - 2], this, exit); }; 
     new Thread(workerThread).Start(); 
    } 

public void pollDevices(IDeviceInterface device, DeviceManager mainUI, ManualResetEvent exit) 
{ 
    while(!exit.WaitOne(1000)) 
    { 
     // do work 
     device.connect(device, this); 
    } 
} 

然後,如果你要停止所有線程,只需調用exit.Set()

+0

我在我的線程proc中使用了一個計時器,因爲我需要根據計時器輪詢設備。這樣我可以實時保持它們的狀態,如果device.connect()被稱爲device.poll() –

+0

hmm,使用這種方法,它可能會讓你的觀點更有意義,它似乎永遠不會進入循環執行代碼.. –

0

我在解決方案http://msdn.microsoft.com/en-us/magazine/cc163644.aspx

這是AbortableThreadPool的一個使用此。可能會爲你工作。

也有點困惑,爲什麼你叫Thread.Abort的在timerElapsed一個線程即將完成反正

+0

意識到這一點後,我張貼並拿出來,哎呀! –