正在解雇线程安全事件? [英] is firing events threadsafe?

查看:54
本文介绍了正在解雇线程安全事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

常用的成语是这样的:


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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆