C# 从不同类更新后台工作程序(最好通过事件)
我的GUI类中有一个后台工作程序C# 从不同类更新后台工作程序(最好通过事件),c#,winforms,events,backgroundworker,C#,Winforms,Events,Backgroundworker,我的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<TradeU
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
}
private void bw\u DoWork(对象发送方,DoWorkEventArgs e)
{
ProgressClass obj=新ProgressClass();
进口商贸易进口商=e.作为进口商的参数;
BackgroundWorker worker=发件人作为BackgroundWorker;
List List=obj.AllocateTrades2(tradeImporter,false);
e、 Result=list;//传递要处理的列表
}
这是我自己的班级。现在,AllocateTrades2
方法已经完成了所有的处理
我的问题是,如何在AllocateTrades2
方法中执行bw.ProgressReport
,该方法位于不同的类中,而不将bw作为参数传递
如果有人向我解释如何处理事件,那就太好了,但如果有另一种优雅的方式。我对想法持开放态度。鉴于
AllocateTrades2
在后台工作程序的上下文中运行,因此它引发的任何事件也会在该上下文中执行
因此,您只需在ProgressClass
中添加一个新事件,比如说NotifyProgress
,并将其绑定到您拥有后台工作程序的类
因此:
这没关系,因为您可以(或者已经)让工人作为这个类的成员
在这种情况下,您需要定义
ProgressClassEventArgs
(EventArgs
子类)并添加int类型的Progress
属性,以匹配ReportProgress
args。如果您不想传入整个BGW(合理地这样做),从而不公开超出其需要知道的内容,一个选项是只传入一个您分配了ReportProgress
调用的委托
将AllocateTrades2
的签名调整为:
public List<TradeUploadInfo> AllocateTrades2(
Importer importer, bool flag, Action<int> reportProgress)
如果您能够/愿意修改obj.AllocateTrades2方法,则可以生成结果,然后在循环中将每个项添加到列表中 例如:
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
}
public IEnumerable AllocateTrades2(进口商贸易进口商,bool foo)
{
foreach(…)
{
TradeUploadInfo栏;//=。。。
// ...
屈服回程杆;
}
}
私有void bw_DoWork(对象发送方,DoWorkEventArgs e)
{
ProgressClass obj=新ProgressClass();
进口商贸易进口商=e.作为进口商的参数;
BackgroundWorker worker=发件人作为BackgroundWorker;
列表=新列表();
foreach(对象AllocateTrades2中的TradeUploadInfo信息(tradeImporter,false))
{
列表。添加(信息);
//…进展
}
e、 Result=list;//传递要处理的列表
}
这里的美妙之处在于,您可以像以前一样使用AllocateTrades2(这意味着您不必修改现有代码或重载函数)(嗯……实际上,您需要修改显式需要列表的代码,可能只需在函数调用后添加
.ToList()
),而不需要添加事件(当涉及到垃圾收集时,可以得到).进程是一个变量吗?如果是,是什么类型?Int?@Alexey它是匿名函数的一个参数。类型是Int
,是的。它基于委托的定义,该定义在:操作
中定义。您可以将那里的类型更改为您想要的任何类型。我得到的委托'System.Func'不带1个参数错误。@ScottChamberlainProgress
本质上是BGW相关方面的替代品。我考虑过提到它,但在这种情况下,他已经利用BGW完成了大部分工作。这当然是另一个有效的选择,如果你想完全废弃BGW,当然值得使用(例如,如果改用TPL)。@AlexeyreportProgress(一些表示当前进度的项目)
private void OnProgressChanged(object sender, ProgressClassEventArgs e)
{
worker.ReportProgress(e.Progress);
}
public List<TradeUploadInfo> AllocateTrades2(
Importer importer, bool flag, Action<int> reportProgress)
obj.AllocateTrades2(tradeImporter, false,
progress => worker.ReportProgress(progress));
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
}