HI,
我有一个按钮点击事件,其中初始化了用户定义的类型,并设置了一个事件。
此按钮被多次使用,我不希望事件堆叠。因此,我已经取消订阅了finally块中的事件。
代码类似于以下内容:
try {
bar = new foo();
bar.event += new event(method);
dosomething()
}
finally {
bar.event -= new event(method);
}
到目前为止似乎工作正常,但是我关注在doSomething方法完成之前处理的finally块,从而使用了事件。
在调用finally块之前,是否允许该方法进行处理?
答案 0 :(得分:6)
我通常做的是每次触发事件时都会检查一个inEvent布尔变量。代码如下所示:
bool inEvent = false;
...
private void Button1_Click(object source, EventArgs e)
{
if (inEvent)
return;
try
{
inEvent= true;
dosomething();
}
finally
{
inEvent = false;
}
}
答案 1 :(得分:3)
当
时,finally块将执行在最后一种情况下,它将访问未初始化的变量栏并抛出NullReferenceException。所以你最好把bar = new foo();
放在try块之前。
答案 2 :(得分:2)
答案 3 :(得分:1)
finally
块在dosomething
返回或抛出之前不会运行。
答案 4 :(得分:1)
最好在生成的事件中取消订阅。
void somewhere()
{
bar = new foo();
bar.event += method;
dosomething()
}
void method(object source, EventArgs e)
{
((bar)source).event -= method;
}
答案 5 :(得分:0)
是(除非在此之前抛出异常)。你的想法很合理。
答案 6 :(得分:0)
据推测,DoSomething()中的逻辑引发了您感兴趣的事件?如果是这样,如果DoSomething()异步引发事件,则会出现问题 - 如果是这种情况,DoSomething可能会返回,那么您最终将运行并取消订阅该事件。当事件最终从DoSomething中启动的代码触发时,你会错过它。
如果DoSomething中没有异步逻辑(即如果事件是同步引发的),那么您的一般方法就可以了。但是你可能想要考虑让DoSomething返回一个值,而不是提出一个事件
答案 7 :(得分:0)
同步调用事件。因此,除非您在DoSomething()
方法中编写任何异步代码,否则最终将在执行完成后始终运行(或抛出异常)。
您似乎得到的是,挂起的事件处理程序引用将阻止收集对象,这可能导致内存问题。您有正确的想法,为了完全释放和反对,您应该在完成后删除所有事件。