我有一张表格。表单有一个逻辑类,可以执行某些操作。我希望表单在响应时完成响应,因此我创建了一个BackgroundWorker对象。
我还想从逻辑类获取更新到表单。我想使用BackgroundWorker的进度更新事件。
所以我在表单上订阅了一个方法to worker.ProgressChanged。
public class MyForm : Form
{
private LogicClass logicObject;
public void StartOperation()
{
BGWorkerBase worker = new BGWorkerBase(logicObject);
worker.DoWork += new DoWorkEventHandler(DoOperation);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(OperationComplete);
worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
worker.RunWorkerAsync();
}
public void DoOperation()
{
logicObject.DoSomething();
}
private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// Update form
}
}
我创建了一个客户Backgroundworker,它订阅逻辑类的更新事件并调用ProgressChanged事件:
public class BGWorkerBase : BackgroundWorker
{
public BGWorkerBase(LogicClass logicObject)
{
// connection is the logic class. it has an update event
logicObject.UpdatePublished += new EventHandler(connection_UpdatePublished);
this.WorkerReportsProgress = true;
}
// Here I invoke the backgroundworker OnProgressChangedEvent
private void connection_UpdatePublished(object sender, EventArgs e)
{
OnProgressChanged(new ProgressChangedEventArgs(0, e));
}
}
问题是当我反复触发操作时,多次发布更新。我检查并发现连接对象有多个工作者订阅了发布事件。所以看来我在这里创造了两个问题:
1.单个事件多次发布。
2.我在连接对象中保留了对后台工作者的参考,这些工作人员应该在完成工作后进行处理。
解决这个问题的最佳方法是什么?我可能能够在完成工作时删除工作者的订阅,但它似乎很脏。有没有更好的方法来管理这种情况?
答案 0 :(得分:4)
当工人完成时,您应该取消订阅该事件。即在代码中的某处,您应该添加以下内容:
logicObject.UpdatePublished -= connection_UpdatePublished;
这将从已注册处理UpdatePublished
事件的委托列表中删除您的事件处理程序。
这个SO问题/答案解释了如何使用事件意外地创建内存泄漏: Why and How to avoid Event Handler memory leaks?