2011-04-06 24 views
0

我正在創建一個使用.Net和Mono的應用程序,它使用了跨線程表單,因爲我的子窗口響應不好。用Mono在C#中交叉線程表單

我用兩種形式創建了一個測試程序:第一個(form1)有一個按鈕(button1),第二個(form2)是空白的,下面的代碼片段。

void openForm() 
{ 
    Form2 form2 = new Form2(); 
    form2.ShowDialog(); 
} 
private void button1_Click(object sender, EventArgs e) 
{ 
    Thread x = new Thread(openForm); 
    x.IsBackground = true; 
    x.Start(); 
} 

這正常NET中,但與單聲道,當你點擊它(標準.ShowDialog()行爲)的第一個窗口不會獲得焦點,而不是.Show()行爲.NET使用。

當我使用.Show(),在.Net和Mono窗口只是閃爍然後消失。如果我在'form2.Show()'之後放置'MessageBox.Show()',它將保持打開狀態,直到您單擊確定。

我在代碼中丟失了什麼,或者單聲道不支持? (我使用單聲道2.8.1)預先

謝謝,阿德里安

編輯:我發現我忘記 'x.IsBackground = TRUE;'在上面的代碼中,子窗口將與主窗口關閉。

回答

0

如果你使用Winforms控件,你總是在主UI線程中「觸摸」對象。

至少 - 在新線程中調用新的Form.ShowDialog()沒有意義。

編輯: 如果你想調用/的BeginInvoke容易的工作,你可以使用擴展方法:

public static class ThreadingExtensions { 
    public static void SyncWithUI(this Control ctl, Action action) { 
     ctl.Invoke(action); 
    } 
} 
// usage: 
void DoSomething(Form2 frm) { 
    frm.SyncWithUI(()=>frm.Text = "Loading records ..."); 

    // some time-consuming method 
    var records = GetDatabaseRecords(); 
    frm.SyncWithUI(()=> { 
     foreach(var record in records) { 
      frm.AddRecord(record); 
     } 
    }); 

    frm.SyncWithUI(()=>frm.Text = "Loading files ..."); 

    // some other time-consuming method 
    var files = GetSomeFiles(); 
    frm.SyncWithUI(()=>{ 
     foreach(var file in files) { 
      frm.AddFile(file); 
     } 
    }); 

    frm.SyncWithUI(()=>frm.Text = "Loading is complete."); 
} 
+0

我沒有訪問任何對象從不同的線程創建它們,我沒有想到調用.ShowDialog()有意義,但這就是我在搜索時發現的所有網站 – 2011-04-07 11:11:55

+0

您應該在UI線程中創建其他Winforms對象。但是在你的代碼中,你創建並顯示了一個新的表單。這不是個好主意,因爲在這種情況下,將所有呼叫保持在正確的線程中更困難。正確的線程是對象創建的線程(調用構造函數的地方)。 – TcKs 2011-04-07 14:53:15

+0

我需要表單獨立運行,所以我應該在同一個線程中使用它,但是在單獨的線程中使用所有耗時的函數?我回避的原因是因爲所有這些。 – 2011-04-08 04:09:05

1

這幾乎從來沒有在一個Windows應用程序有多個線程的談話做正確的事到共享相同消息泵的一個窗口或多個窗口。

而且很少有必要擁有多個消息泵。

要做到這一點的正確方法是使用「Invoke」方法手動將所有工作線程從工作線程封送到Window,或者使用類似BackgroundWorker的東西來隱藏細節。

總結:

  • 不要堵住了耗時的計算或I/O
  • 不要從多個線程交談的UI用戶界面線程。
+0

正如我在我的第一篇文章中提到的,我有單獨的線程的唯一原因是性能,我曾考慮使用單獨的線程而不是表單創建其他所有內容,但它需要大量的代碼重寫,我可能會最終做到這一點,但我希望能像這樣工作。 Mono也不支持.Net的功能嗎?還是有辦法做到這一點? – 2011-04-07 11:02:27