2009-05-21 52 views
2

我有一個關於事件.NET(C#)的問題。我必須爲幾種情況編寫代碼,其中我有一個後臺任務正在運行,並且我想通知主線程或控制器類發生了某些事情,例如已完成任務或已完成複製文件,但是我不' t希望後臺任務等待主線程的委託來處理事件。如何在不等待事件偵聽器運行的情況下觸發事件?

我想做一些類似消息傳遞的事情:發送消息,但誰在乎他們如何處理它。

例如:

一個類被寫入順序處理幾個過程,一個在另一個之後。每個進程都需要在後臺線程上運行。當工作完成時,事件觸發並告訴控制器它已完成(比方說使用OnCompleted()方法)

問題是如果控制器的事件處理程序用於啓動後續進程,則先前進程的OnComplete方法停留在調用堆棧上(永遠不會執行完畢),直到所有進程完成。

在這種情況下,後臺任務如何通知控制器類工作完成而不在堆棧上保留事件提升方法?

示例2:備份程序。

後臺線程運行將每個文件複製到目標。背景需要通知 UI是最後一個被複制的文件,但它不需要等待UI更新。相反,它只是想說,「順便說一句,這裏有一些信息,現在讓我回去工作。」事件監聽器不應該阻止事件提升器的處理。

回答

2

提高(如前所述)事件時,你可以做一個異步調用,或只是提高事件本身在後臺線程:

void OnUpdated(EventArgs e) { 
    EventHandler h = this.Updated; 
    if (h != null) h(e); 
} 

void DoStuff() { 
    BigMethod(); 
    ThreadPool.QueueUserWorkItem(OnUpdated, EventArgs.Empty); 
    BigMethod2(); 
} 

如果提高異步,多聽衆將處理您的事件在同一時間。至少,這需要一個線程安全的EventArg類。如果你期望他們也和你的班級進行互動,那麼你應該非常仔細地記錄文件,或者使其線程安全。

在後臺線程中引發事件對您的類方法帶來相同的警告,但您不必擔心EventArgs類本身。

1

讓第一個事件不做任何事情,但開始線程,然後它不關心什麼其他事件監聽器。

+0

我該怎麼做在C#中? – 2009-05-21 00:35:14

+0

好吧,你似乎知道如何開啓另一個線程。只要有第一個事件監聽器這樣做(只要你用事件創建對象,分配處理器 – 2009-05-21 23:10:05

3

聽起來好像你試圖異步調用事件調用列表中的委託。

我建議你閱讀.NET Asynchronous Events To Send Process Status To User Interface

.NET框架爲我們提供了籌款活動,在我們班 概念(和其他 項目)是異步的。 這意味着我們可以通過這樣的方式提高事件 ,使得該事件(典型地爲 用戶界面)的用戶不會在提出 事件的方法中阻止 處理。好處是它不會對我們的業務層 方法的性能產生負面影響。

0

對於你的情況2的備份計劃。代碼示例將異步觸發文件副本,一旦完成複製,它將調用回調方法。在回調,如果你不想等待UI更新,那麼你將不得不調用UI更新代碼以異步方式

您可以使用異步委託

public class AsyncFileCopier 
    { 
     public delegate void FileCopyDelegate(string sourceFile, string destFile); 

     public static void AsynFileCopy(string sourceFile, string destFile) 
     { 
      FileCopyDelegate del = new FileCopyDelegate(FileCopy); 
      IAsyncResult result = del.BeginInvoke(sourceFile, destFile, CallBackAfterFileCopied, null); 
     } 

     public static void FileCopy(string sourceFile, string destFile) 
     { 
      // Code to copy the file 
     } 

     public static void CallBackAfterFileCopied(IAsyncResult result) 
     { 
      // Notify UI by calling an async del (probably using fire & forget approach or another callback if desired) 
     } 
    } 

你可以稱其爲:

AsyncFileCopier.AsynFileCopy("abc.txt", "xyz.txt"); 

這個link告訴你asyn編碼的不同技術

相關問題