我的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
方法已完成所有处理。
我的问题是,我如何在bw.ProgressReport
方法中执行AllocateTrades2
,该方法在不同的类中,而不将bw作为参数传递?
如果有人向我解释如何使用事件来解决这个问题会很棒,但如果还有另一种优雅方式的话。我很开心。
答案 0 :(得分:5)
如果你不想传递整个BGW(理所当然地),以便不暴露超出它需要知道的内容,一个选择就是传入你指定{{1}的委托。致电。
将ReportProgress
的签名调整为:
AllocateTrades2
从该方法中适当地调用public List<TradeUploadInfo> AllocateTrades2(
Importer importer, bool flag, Action<int> reportProgress)
委托。
然后将调用调整为reportProgress
,如下所示:
AllocateTrades2
答案 1 :(得分:1)
好吧,鉴于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。
答案 2 :(得分:1)
如果您能够/愿意修改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()
,并且您不需要添加事件(当它可以获得a little tricky时来垃圾收集)。