gpt4 book ai didi

c# - 安全地引发事件线程

转载 作者:太空宇宙 更新时间:2023-11-03 11:52:13 25 4
gpt4 key购买 nike

我确定我以前见过这种情况,但我想知道我应该如何安全地引发事件线程。

我有一个消息发送线程,看起来有点像。

while(_messages > 0){

Message msg;
// get next message

if (MessageDispatched != null)
MessageDispatched(this, new MessageDispatchedEventArgs(msg.Msg, msg.Params));
}

我可以看到 MessageDispatched 在检查后可能变为 null。来 self 看过的 MS 博客:

var handler = MessageDispatched;

if (handler != null)
handler(this, new MessageDispatchedEventArgs(msg.Msg, msg.Params));

这确实阻止了在检查发生后引用变为 null 的可能性。我想知道如何处理委托(delegate)被处置的情况(或者即使可以?)

我是否只需要围绕它进行尝试/捕获,因为它可能很少发生?

编辑

阅读答案后,我考虑让我的类(class)来处理这个问题 - 很快它看起来像下面的东西,但我遇到了一些问题,使它不像我想要的那样干净 - 也许有人知道如何这样做吗?

public class ThreadSafeEvent<TDelegate> 
// where TDelegate : Delegate why is this a non allowed special case???
{
List<TDelegate> _delegates = new List<TDelegate>();

public void Subscribe(TDelegate @delegate)
{

lock (_delegates)
{
if (!_delegates.Contains(@delegate))
_delegates.Add(@delegate);
}
}

public void Unsubscibe(TDelegate @delegate)
{
lock (_delegates)
{
_delegates.Remove(@delegate);
}
}


// How to get signature from delegate?
public void Raise(params object[] _params)
{
lock (_delegates)
{
foreach (TDelegate wrappedDel in _delegates)
{
var del = wrappedDel as Delegate;
del.Method.Invoke (del.Target, _params);
}
}
}
}

最佳答案

后一种结构将确保您不会在非安腾架构上调用处理程序时出现空引用异常。

但是,这会导致另一个可能的问题——注册事件处理程序的客户端可能会在处理程序被删除后调用该处理程序。防止这种情况的唯一方法是序列化引发事件并注册处理程序。但是,如果您这样做,就会出现潜在的死锁情况。

简而言之,这可能会破坏三种潜在的方式——我采用你在这里完成的方式(MS 推荐)并接受事件处理程序可能在它被调用之后被调用未注册。

关于c# - 安全地引发事件线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1795531/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com