正在解雇线程安全事件? [英] is firing events threadsafe?
问题描述
常用的成语是这样的:
MyDelegate d = MyEvent;
//事件的接收者在另一个线程中的这一行之后取消订阅
if(d!= null)
d(this,EventArgs.Empty);
如果我认为它是对的有可能在一个多线程的
环境中,一个对象可能会在*取消订阅
之后收到一个事件吗?
obj.MyEvent - = myMethod;
//这个对象在这个
行之后仍然可以收到一个事件吗?
the common used idiom is like this:
MyDelegate d = MyEvent;
// receiver of the event unsubscribes after this line in another thread
if (d!=null)
d(this, EventArgs.Empty);
Am I right if I think that it is possible that in a multithreaded
environment an object may receive an event *after* it has unsubscribed from
that event?
obj.MyEvent -= myMethod;
// is it possible that this object can still receive an event after this
line?
推荐答案
cody< de ******** @ gmx.de>写道:
cody <de********@gmx.de> wrote:
常用的成语是这样的:
MyDelegate d = MyEvent;
//事件的接收者在另一个帖子中的这一行之后取消订阅
if(d!= null)
d(this,EventArgs.Empty);
如果我认为在多线程
环境中有可能对象可能会在*取消订阅该事件之后收到一个事件*?
是的。
obj.MyEvent - = myMethod;
//这个对象在此之后仍然可以收到一个事件/> line?
the common used idiom is like this:
MyDelegate d = MyEvent;
// receiver of the event unsubscribes after this line in another thread
if (d!=null)
d(this, EventArgs.Empty);
Am I right if I think that it is possible that in a multithreaded
environment an object may receive an event *after* it has unsubscribed from
that event?
Yes.
obj.MyEvent -= myMethod;
// is it possible that this object can still receive an event after this
line?
绝对。实际上,上面的代码不是线程安全的 - 请参阅
http://www.pobox.com/~skeet/csharp/t...ckchoice.shtml
请记住,在多个 - 处理器机器,两个语句
可以*同时执行*!
-
Jon Skeet - < sk *** @ pobox.com>
http:// www .pobox.com / ~siget
如果回复小组,请不要给我发邮件
Absolutely. Indeed, the code above isn''t thread-safe - see
http://www.pobox.com/~skeet/csharp/t...ckchoice.shtml
Bear in mind that on a multi-processor machine, the two statements
could be executing at *exactly* the same time!
--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
所以最后哪个方法用于线程安全点火
事件?
保护虚拟OnSomeEvent(EventArgs e)
{
lock(someEventLock)
{
if(someEvent!= null)
{
someEvent(this,e);
}
}
}
此方法可以,根据o你的网站,导致僵局。
保护虚拟OnSomeEvent(EventArgs e)
{
if(MyEvent!= null)
{
MyEvent(this,e);
}
}
这可能会导致NullReferenceException ..
protected virtual OnSomeEvent(EventArgs e)
{
委托someEvent = MyEvent;
if(someEvent!= null)
someEvent(this,e);
}
和这个方法可能会导致一个对象在*
取消订阅后收到一个事件*。
那么最好的方法是什么?以下是最佳解决方案吗?
保护虚拟OnSomeEvent(EventArgs e)
{
尝试
{
MyEvent(this,e);
}
catch(NullReferenceException)
{
}
}
***通过Developersdex发送 http://www.developersdex.com ***
So at the end which method shall be used for threadsafe firing of
events?
protected virtual OnSomeEvent(EventArgs e)
{
lock (someEventLock)
{
if (someEvent != null)
{
someEvent(this, e);
}
}
}
this method may, according to your website, lead to a deadlock.
protected virtual OnSomeEvent(EventArgs e)
{
if (MyEvent != null)
{
MyEvent(this, e);
}
}
this may lead to an NullReferenceException..
protected virtual OnSomeEvent(EventArgs e)
{
Delegate someEvent = MyEvent;
if (someEvent != null)
someEvent (this, e);
}
and this method could cause that an object receives an event *after*
unsubscribing to it.
So what is the best way to do it? Is the following the best solution?
protected virtual OnSomeEvent(EventArgs e)
{
try
{
MyEvent(this, e);
}
catch (NullReferenceException)
{
}
}
*** Sent via Developersdex http://www.developersdex.com ***
cody manix< de ******** @ gmx.net>写道:
cody manix <de********@gmx.net> wrote:
所以最后哪个方法应该用于
事件的线程安全触发?
受保护的虚拟OnSomeEvent(EventArgs e)
{
lock(someEventLock)
{
if(someEvent!= null)
{
someEvent(this,e);
}
}
}
这种方法可能会根据您的网站导致僵局。
是的。
保护虚拟OnSomeEvent(EventArgs e)
{
if(MyEvent!= null)
{
MyEvent(this,e);
}
这可能会导致NullReferenceException ..
Yup 。
protected virtual OnSomeEvent(EventArgs e)
{
委托someEvent = MyEvent;
if(someEvent!= null)
someEvent(this,e );
}
这不是线程安全的。使用(根据网站):
protected virtual OnSomeEvent(EventArgs e)
{
SomeEventHandler handler;
锁定(someEventLock)
{
handler = someEvent;
}
if(handler) != null)
{
handler(this,e);
}
}
没有办法避免事件被解雇的可能性
一个对象取消订阅后。
和这个方法可能会导致某个对象在取消订阅后收到一个事件*
那么最好的方法是什么?以下是最佳解决方案吗?
受保护的虚拟OnSomeEvent(EventArgs e)
{
尝试
{My / MyEvent(this,e);
}
catch(NullReferenceException)
{
}
}
So at the end which method shall be used for threadsafe firing of
events?
protected virtual OnSomeEvent(EventArgs e)
{
lock (someEventLock)
{
if (someEvent != null)
{
someEvent(this, e);
}
}
}
this method may, according to your website, lead to a deadlock.
Yup.
protected virtual OnSomeEvent(EventArgs e)
{
if (MyEvent != null)
{
MyEvent(this, e);
}
}
this may lead to an NullReferenceException..
Yup.
protected virtual OnSomeEvent(EventArgs e)
{
Delegate someEvent = MyEvent;
if (someEvent != null)
someEvent (this, e);
}
That''s not thread-safe. Use (as per the website):
protected virtual OnSomeEvent(EventArgs e)
{
SomeEventHandler handler;
lock (someEventLock)
{
handler = someEvent;
}
if (handler != null)
{
handler (this, e);
}
}
There''s no way of avoiding the possibility of an event being fired
after an object has unsubcribed from it.
and this method could cause that an object receives an event *after*
unsubscribing to it.
So what is the best way to do it? Is the following the best solution?
protected virtual OnSomeEvent(EventArgs e)
{
try
{
MyEvent(this, e);
}
catch (NullReferenceException)
{
}
}
绝对不是。这不是线程安全的,滥用异常,并且通常是令人讨厌的
。
如果您需要确保某些事情不会发生在你取消订阅
后,你应该在
类中有一个单独的布尔变量来接收事件,并在你取消订阅之前设置它。然后
如果在事件被触发时设置了该变量,则返回。
-
Jon Skeet - < sk***@pobox.com>
http://www.pobox。 com / ~siget
如果回复小组,请不要给我发邮件
Absolutely not. That''s not thread-safe, abuses exceptions, and is
generally nasty.
If you need to make sure that something doesn''t happen after you''ve
unsubscribed, you should have a separate boolean variable within the
class which receives the event, and set it before you unsubscribe. Then
if that variable is set when the event is fired, just return.
--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
这篇关于正在解雇线程安全事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!