2011-02-17 136 views
0

我的問題是我需要一個線程在Serialports上進行操作。 我實現了一個從其他對象調用方法的工作類來讀取串行端口的值。當私有volatile屬性爲真時,線程應該這樣做。如果它設置爲false,則循環停止。在循環中,我提出了一個事件來將eventargs傳遞給GUI,以便它可以被更新。在我的WPF GUI中,我正在捕獲事件並處理事件,當工作夥伴仍在工作時(另一個volatile屬性)。c#wpf線程沒有正確終止

當我不在工人類中觸發事件時,一切都正常工作。 但是,當我觸發事件的線程是不會停止的狀態,有時(並不總是)

工人代碼:

public void StartWork() 
    { 
     int i = 0; 
     while (this._continue) 
     { 
      this.StillRunning = true; 
       try 
       { 

        if (measureDispesner) 
        { 
         Dispenser.GetStatus(); 
        } 
        if (MeasureScale) 
        { 

         Dispenser.Scale.Weigh(); 
        } 

        OnProgressChanged(new ProgressChangedArgs(Dispenser, Dispenser.Scale)); 
        Console.WriteLine("Executed measuring " + i++.ToString() + " ScaleWeight: " + Dispenser.Scale.Status.CurrentStableWeight.ToString()); 
       } 
       catch (Exception e) 
       { 
        //throw e.InnerException; 
       } 
       finally 
       { 
        // System.Threading.Monitor.Exit(this); 
       } 


     } 
     Console.WriteLine("Stopped after: " + i++.ToString()); 

     this.StillRunning = false; 


    } 

事件處理在WPF GUI:

void worker_ProgressChanged(object sender, M5.Objects.Dispenser.ProgressChangedArgs e) 
    { 
     M5.Objects.Dispenser.Worker MyWorker = (M5.Objects.Dispenser.Worker)sender; 
     while (MyWorker.Continue) 
     { 
      // Wait while the worker is still running - code angs here 
      //return; 
     } 
     System.IO.MemoryStream ms;// = M5.Support.ResourceManager.ResMan.ConvertImageToMemoryStream(M5.Support.ResourceManager.ResMan.BottleImage); 


     if (this.objDispenser.IsAvalaible) 
     { 
      this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, (Action)delegate() 
      { 
       this.txtComPort.Text = e.DispenserPort; 
       this.lblDispenserStatus_Dispenser.Content = e.DispenserMedikament; 

...

我在做什麼錯?我如何更新我的GUI線程安全?我也試過監視器,以防止其他代碼再次調用workerthread函數... 先謝謝你,馬克!


感謝您的快速回復!

不,這不是我想要的,而是試圖阻止在事件處理程序中執行GUI代碼,因爲Thread.Join()在嘗試執行GUI代碼時不起作用。所以我從來沒有停過的線程。

將_continue標誌傳遞給eventargs時,我現在可以阻止執行GUI代碼。這工作到現在好。

void worker_ProgressChanged(object sender, M5.Objects.Dispenser.ProgressChangedArgs e) 
    { 
     if (e.StopUI) 
     { 
      return; 
     } 

但是對於感興趣,您是否意味着清除屬性?它是否設置爲空?

回答

0

但是當我火線程是不會停止的狀態,有時(並不總是)

啊,又愛在一些額外否定投擲事件。如果我正確理解了您的代碼,請在您的worker_ProcessChanged事件處理程序中,您正在等待線程關閉(MyWorker.Continue變爲false)。那真的是你想要的嗎?據我所知,您並未在任何地方清除Continue_continue

也許你想在你的事件處理程序中的東西更符合這一點?

void worker_ProgressChanged(object sender, M5.Objects.Dispenser.ProgressChangedArgs e) 
{ 
    M5.Objects.Dispenser.Worker MyWorker = (M5.Objects.Dispenser.Worker)sender; 
    MyWorker.Continue = false; 
    while (MyWorker.StillRunning) 
    { 
     // Wait here... 
    } 

    // Do something else 
} 

如果不是這樣,那麼再次重複您的問題並更清楚地說出它可能會是謹慎的。

+0

至少我找到了一個可以正常工作的方法:我將continuearg和eventargs一起傳遞,並在繼續爲false時阻止執行gui代碼。 – 2011-02-17 11:24:36