c# - 作为事件处理程序的匿名方法
问题描述
编辑:这个问题不是关于如何取消订阅事件,因为如果我愿意,我知道该怎么做。问题是在我的特定场景中是否与垃圾收集存在冲突。
在我不久前编写的一些代码中,我通过匿名方法注册了一个事件( CheckExecution
,拥有者,见下面的代码)。isoDataTemp
但是现在我想到给一个事件分配一个匿名方法是非常邪恶的,因为没有办法从事件中注销该方法,对吧?我曾经遇到过一个无法被垃圾收集的对象的问题,因为一个事件仍然指向它。
所以我想知道我是否可以在这里遇到麻烦。我的自发反应是“不,因为匿名方法属于 MainForm,它的生命周期比它的isoDataTemp
成员长”。但我不确定。闭包呢?匿名方法是否完全属于 MainForm。我很困惑...
public partial class MainForm : Form
{
// ...
void BackgroundWorkerISOAnalysisDoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
int prog = 0;
isoDataTemp.CheckExecution += () =>
{
prog += 12;
if (prog > 100) prog = 100;
worker.ReportProgress(prog);
return !worker.CancellationPending;
};
isoDataTemp.Analyze();
if (worker.CancellationPending) e.Cancel = true;
}
}
解决方案
要取消注册您拥有的事件的所有事件处理程序,只需使用以下代码:
isoDataTemp.CheckExecution = null;
请注意,这适用于匿名和非匿名事件处理程序。
从您的示例中,您可以将此代码添加到 OnFormClosing 事件中,以确保正确且完全删除分配给您的 isoDataTemp 对象的事件。
请注意,如果 isoDataTemp 对象是表单对象的子对象,那么当您的 Form 对象被销毁时,它将被删除,并将与被销毁的 Form 对象实例一起进行垃圾收集,如预期的那样。
推荐阅读
- c# - 检查字符串是否在文件中,如果是,则替换包含该字符串的特定行
- apache-spark - Spark:有没有办法在分布的每台本地机器上使用资源?
- ios - 在 didset 之后对象值不会改变
- databricks - Spark Streaming Notebook x 小时
- powershell - 从各种名称列表中获取 SamAccountName
- python - Python如何添加多个列表的总和
- c - 在 C 中打印 SQL
- sql - 与多个表的多对多关系
- terraform - 更新 template_file 中的计数不会影响输出
- laravel - Laravel 图像上传仅返回某些图像上的部分对象