簡體   English   中英

后台工作人員從不同的班級更新(最好通過活動)

[英]Background Worker Updating from a different class (preferably via events)

我的GUI類中有一個后台工作程序。

private void bw_DoWork(object sender, DoWorkEventArgs e)
{
    ProgressClass obj = new ProgressClass();
    Importer tradeImporter = e.Argument as Importer;
    BackgroundWorker worker = sender as BackgroundWorker;
    List<TradeUploadInfo> list = obj.AllocateTrades2(tradeImporter, false);
    e.Result = list; //Passes the list for processing
}

進口商是我自己的班級。 現在, AllocateTrades2方法已完成所有處理。

我的問題是,如何在AllocateTrades2方法中執行bw.ProgressReport ,該方法在不同的類中,而不將bw作為參數傳遞?

如果有人向我解釋如何用事件做這件事,但是如果還有另一種優雅的方式,那會很棒。 我很開心。

如果你不想傳遞整個BGW(理所當然地),以便不暴露超出它需要知道的內容,一個選擇就是傳入一個為你分配ReportProgress調用的委托。

AllocateTrades2的簽名調整為:

public List<TradeUploadInfo> AllocateTrades2(
    Importer importer, bool flag, Action<int> reportProgress)

從該方法中適當地調用reportProgress委托。

然后將調用調整為AllocateTrades2如下所示:

obj.AllocateTrades2(tradeImporter, false,
     progress => worker.ReportProgress(progress));

好吧,鑒於AllocateTrades2在后台工作程序的上下文中運行,它所引發的任何事件也會在該上下文中執行。

因此,您需要做的就是在ProgressClass添加一個新事件,比如NotifyProgress ,並將其綁定到您擁有后台工作者的類。

所以:

 //In class ProgressClass. 
 public event EventHandler<ProgressClassEventArgs> NotifyProgress = (s, e) => {};

接下來:

 private void bw_DoWork(object sender, DoWorkEventArgs e)
 {
     ProgressClass obj = new ProgressClass();

     //Here you hook up the event
     obj.NotifyProgress += this.OnProgressChanged;

     Importer tradeImporter = e.Argument as Importer;
     BackgroundWorker worker = sender as BackgroundWorker;
     List<TradeUploadInfo> list = obj.AllocateTrades2(tradeImporter, false);
     e.Result = list; //Passes the list for processing
 }

事件處理程序如下所示:

private void OnProgressChanged(object sender, ProgressClassEventArgs e) 
{
   worker.ReportProgress(e.Progress);
}

沒關系,因為你可以(或者你已經做過)將工人作為這個班級的成員。

您需要定義ProgressClassEventArgsEventArgs子類)並在此情況下添加類型為int的Progress屬性,以匹配ReportProgress args。

如果你能夠/願意修改obj.AllocateTrades2方法,你可以yield結果,然后每個項目添加到列表中的一個循環。

例:

public IEnumerable<TradeUploadInfo> AllocateTrades2(Importer tradeImporter, bool foo)
{

    foreach( ... )
    {
        TradeUploadInfo bar; // = ...
        // ...
        yield return bar;
    }

}

private void bw_DoWork(object sender, DoWorkEventArgs e)
{
    ProgressClass obj = new ProgressClass();
    Importer tradeImporter = e.Argument as Importer;
    BackgroundWorker worker = sender as BackgroundWorker;
    List<TradeUploadInfo> list = new List<TradeUploadInfo>();
    foreach ( TradeUploadInfo info in obj.AllocateTrades2(tradeImporter, false) )
    {
        list.Add( info );
        // ... progress
    }
    e.Result = list; //Passes the list for processing
}

這里的美妙之處在於您可以 像以前一樣 使用AllocateTrades2 (意味着您不必修改現有代碼或重載函數) 嗯..實際上,您需要修改明確期望List的代碼,可能通過在函數調用之后添加.ToList()並且您不需要添加事件(在垃圾收集時可能會有點棘手 )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM