2010-05-05 400 views
2

我想基於在後臺線程進行輪詢在.NET應用停用UI的部分。後臺線程檢查應用程序使用的全局數據庫連接是否仍然可用並且可操作。多線程委託/事件

我需要做的,寧願做沒有在UI線程上投票,是添加一個事件處理程序,可以通過後臺線程,如果連接狀態的變化而提高。這樣,任何表單都可以有一個處理程序,它將禁用需要連接功能的那些UI部分。

試圖在保持線的子類使用直事件聲明,並在後臺線程引發事件引起關於從其它線程訪問UI控件跨線程執行錯誤。

顯然,有做這種正確的方式,但我們用有限的事件(單線程應用爲主),幾乎與代表沒有經驗。我已經閱讀了代表的文檔和示例,它似乎更接近我們需要的內容,但我不確定如何在此實例中使其工作。

的應用主要是寫在VB.NET,但在C#示例或幫助是沒關係。

+0

在DOTNET,你不應該有一個不斷打開全局連接。閱讀ConnectionPooling。 http://stackoverflow.com/questions/2715714/ – 2010-05-05 22:00:51

+0

@亨克霍爾特曼:如果你不知道他的情況,你不能做出這樣的表述。此外,微軟在框架中包含的提供商也不推薦使用。 – AMissico 2010-05-05 22:05:11

+0

@amissico:使用我的技巧下面,它並不重要(它同樣適用於...) – 2010-05-05 22:07:22

回答

2

可以名帥事件的飼養返回到UI線程。由於這可能(如果你設計的很好)是從一個單獨的類中完成的,我的建議是將當前SynchronizationContext的副本傳遞到處理後臺進程的類中。

下面是在C#中的一些示例代碼:

public class BackgroundWork 
{ 
    public SynchronizationContext Context { get; private set; } 
    public BackgroundWork(SynchronizationContext context) 
    { 
     this.Context = context; 
    } 

    // Thread handler, etc... 

    // Method to raise event 
    void RaiseEvent() 
    { 
     Context.Post((state) => 
     { 
      // Raise the event 
      this.ConnectionStatusChanged(this, EventArgs.Empty); 
     }, null); 
    } 
} 

然後,當你構建類(在你的UI線程),它傳遞當前環境:

BackgroundWork worker = new BackgroundWork(SynchronizationContext.Current); // This passes the UI thread context... 
worker.Start(); 

(這由方式,是BackgroundWorker類使用,這就是爲什麼它的工作原理相同的Windows窗體和WPF相同的技術......)

0

通過使用Control.Dispatcher.Invoke解決跨線程執行錯誤:

public void EnventHandlerMethod(object sender, EventArgs e) 
{ 
    myLabel.Dispatch.Invoke(new Action(() => { myLabel.Content = "Updated"; })); 
} 

事件處理程序可以根據你處理事件而變化的簽名。當然,如果你只是改變另一個線程中的控件,你只需要上述方法的主體。

而且這個(我認爲)假設.NET 3.5

+0

這解決了它在客戶端訂閱端,但不是在連接池端... – 2010-05-05 22:05:52

0

嘗試要改變控制,或任何控制的Invoke方法真的,並提供一個小功能,做你想做的工作。或者參見BeginInvoke異步執行。

只是要小心線程問題,更改變量「主」線程改變等

+0

這(幾乎)解決了它客戶端訂閱端,但不在連接池端... – 2010-05-05 22:06:38