[英]Background worker class and passing messages using progress events from a different class in c#
[英]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);
}
沒關系,因為你可以(或者你已經做過)將工人作為這個班級的成員。
您需要定義ProgressClassEventArgs
( EventArgs
子類)並在此情況下添加類型為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.