从不同的类更新(最好通过事件)
本文关键字:事件 更新 | 更新日期: 2023-09-27 18:14:55
我有一个后台工作在我的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
}
Importer是我自己的类。现在,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
,并将它绑定到你拥有后台worker的类。
:
//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);
}
没关系,因为你可以(或者你已经这样做了)把worker作为这个类的成员。
您需要定义ProgressClassEventArgs
(EventArgs
子类),并在本例中添加一个int类型的Progress
属性,以匹配ReportProgress
参数。
如果您能够/愿意修改对象。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 .ToList()
),并且不需要添加事件(当涉及到垃圾收集时,这可能会变得有点棘手)。