在系統運行中,如果有多個線程正在運行,並且不影響主線程的運行情況下,如果需要打開一個Dialog,設置一些參數,保存並關閉,但是,會發現,在主窗體中的線程如果沒有結束前是無法關閉彈出的對話框的.下面是錯誤和正確的兩種方法:
一.傳統錯誤的方法
- private void ConfigToolStripMenuItem_Click(object sender, EventArgs e)
- {
- //直接彈出創建的對話框
- MyDialog dlg = new MyDialog();
- dlg.ShowDialog(this);
- dlg.Dispose();
- }
這種方法,在調試中可以發現,雖然彈出的對話窗體中的代碼有運行,但是,在多線程運行結束前,是不會運行的dlg.Dispose();這行代碼上的.所以窗體是無法關閉的.當然,我也試過在子窗體代碼中使用this.Close();來關閉,也是不行的.
二.使用線程委託彈出對話框
- private void ConfigToolStripMenuItem_Click(object sender, EventArgs e)
- {
- //線程運行Dialog方法進行委託
- Thread ShowDialog = new Thread(Dialog);
- //這行代碼一定要有,否則第二次運行就會出錯,關閉不了對話框
- ShowDialog.IsBackground = true;
- ShowDialog.Start();
- }
- //委託彈出對話框
- delegate void ThreadDialog();
- //判斷是否需要進行委託運行方法
- private void Dialog()
- {
- //顯示配置對話框
- if (this.InvokeRequired)
- this.Invoke(new ThreadDialog(Dialog));
- else
- {
- //執行委託的代碼
- MyDialog dlg = new MyDialog();
- dlg.ShowDialog(this);
- dlg.Dispose();
- }
- }
小結
這樣在運行委託的時候就可以正常的關閉對話框了.對話框中的代碼也是可以運行的.在多線程的程序中,界面的操作遇到的問題比較複雜,一般是使用與其他線程並行的線程委託進行.
在多線程中還存在一個問題,子窗口中如果訪問了,一些公共數據,發生阻塞時,也是無法正常關閉窗口的,只能等待互斥的釋放了.