我正在編寫一個程序,它從串口接收數據並更新UI元素(如文本框,標籤等)。定時器用於頻繁向設備發送命令,作爲響應設備返回一些顯示的數據。一切安好。現在,如果我移動主表單或將其最小化,那麼接收代碼正在運行的線程退出(如我所想)。移動主窗體是否有可能導致線程退出?我的程序中可能存在什麼問題?爲什麼數據接收停止?可行的解決方案?線程退出問題
線程退出問題
回答
您的行爲(移動/最小化的形式)將不會影響在代碼中創建線程落後於大多數情況下。數據線更新UI(也許使用像myControl.Invoke)將正常工作,甚至要移動的形式或最小化形式(但如果你關閉窗體不中止更新線程,你會得到例外)。所以你不應該擔心這個。相反,我認爲您需要檢查移動事件背後的代碼或最小化表單事件。提供一些代碼有助於找出原因。
有一個稱爲線程調試窗口。打開斷點時打開程序並打開線程窗口。當您的線程正在接收數據時,應至少列出兩個線程ID,UI線程和線程獲取和接收串行數據。您可能想要命名您的線程,以便在調試器中更容易看到,否則只會有線程ID。從那裏應該給出一些線索,說明爲什麼或至少在退出時。
在你的線程代碼,以及你的UI代碼認沽斷點進行監控。這個問題相當模糊,但是調試和觀察線程應該有幫助。
您在resieving線程更新UI元素。
這意味着,你必須調用控件上UI更新調用,因爲它們不是在另一個線程創建的。
所以,我猜reciever的工作原理如下:
while(!Application.IsApplicationExiting)
{
if (!serial.IsReady) break;
...
Data data = serial.GetData();
string text = GetBaudRate(data);
ui.Invoke((Label label) => label.Text = value, txtBauldRateLabel);
...
}
此時,你應該知道,在這種情況下,這個線程被阻塞,直到調用UI線程結束,但interesing部分當您嘗試調整大小或定位應用程序窗口時,對UI線程的更新也會阻止。
當您嘗試單擊並按住應用程序的某個欄上的鼠標右鍵時,您的UI線程塊會被阻止。
因此,您鎖定了接收器的主循環,在設備發生超時的情況下實際上不會被阻塞,這會引起接收器關閉(將串行狀態更改爲未就緒狀態)。
我建議你使用解鎖調用的BeginInvoke()重寫你的應用程序:
while(!Application.IsApplicationExiting)
{
...
ui.BeginInvoke((Label label) => label.Text = value, txtBauldRateLabel);
...
}
你崩潰的計時器線程,因爲你從中直接更新表單控件...你可以」不要那樣做!您必須調用Invoke(),以便您的代碼從主UI線程執行。
我在您的其他問題發佈了一個答案......這裏要再次重申:
我的猜測是,你崩潰的計時器線程,因爲你無法更新從另一個表單控件線程沒有問題...你必須創建一個在主UI線程下運行的委託。你通過測試Form.InvokeRequired
來做到這一點,如果它是真的,則調用Form.Invoke
。
發生了什麼:您的計時器線程正在更新窗體上的文本框或其他控件。您調整大小或最小化,並且這些表單控件的句柄無效...您不能再使用它們了。除了你的計時器線程仍在運行並試圖使用它們。崩潰!
多線程窗體上的一個很好的例子是here。重要的部分是:
delegate void SetBoolDelegate(bool parameter);
// This would be your timer tick event handler...
void SetInputEnabled(bool enabled) {
if(!InvokeRequired) {
button1.Enabled=enabled;
comboBoxDigits.Enabled=enabled;
numericUpDownDigits.Enabled=enabled;
}
else {
Invoke(new SetBoolDelegate(SetInputEnabled),new object[] {enabled});
}
}
在這個例子中,你測試了InvokeRequired。如果它是假的,那麼你在主UI線程上運行,並可以直接設置控件屬性。如果它是真的,你調用Invoke(),傳遞一個將從主UI線程調用的函數。
在此示例中,您調用的函數/委託與您所在的函數是相同的,但它不一定是。但是您可以將它傳遞給計時器滴答事件處理程序,讓它在主線程上執行。
- 1. 進程退出問題線程未成功退出
- 2. Objective-C線程:退出線程,保留問題
- 3. 問題已退出進程
- 4. 當主線程退出時,如何讓子線程退出?
- 5. Netbeans問題:UI退出後是否有線程仍在運行?
- 6. 退出按鈕退出後的問題
- 7. POSIX線程和退出線程
- 8. 退出守護進程的問題
- 9. 退出應用程序的問題
- 10. Win32線程意外退出
- 11. 關於線程退出
- 12. 線程退出回調
- 13. 掛鉤線程退出
- 14. 線程退出事件 - C++
- 15. Python,線程永不退出
- 16. 退出產卵線程
- 17. 棧,而退出線程
- 18. Python線程退出代碼
- 19. Android線程主要退出
- 20. 關於退出和退貨的問題?
- 21. Django的退出問題
- 22. 退出Jmeter的問題
- 23. Android退出AsyncTask問題
- 24. 退出應用程序安全退出Qt線程
- 25. C:輸出前multithreading-父線程退出
- 26. 主線程退出程序終止?
- 27. 如何退出多線程程序?
- 28. 線程問題
- 29. 線程問題
- 30. 線程問題
您沒有發佈您的代碼。這是我無法幫助你的相同原因[上一次你問這個問題](http://stackoverflow.com/questions/4667272/receiving-data-from-serialport-stops-when-main-form-is-最小化或 - 移動)。 – 2011-01-14 06:49:36