gpt4 book ai didi

c# - 正确通知系统范围内命名的手动重置事件的所有监听器,然后立即重置它

转载 作者:可可西里 更新时间:2023-11-01 13:26:29 25 4
gpt4 key购买 nike

我通过执行以下操作创建了一个系统范围的手动重置事件:

EventWaitHandle notifyEvent = new EventWaitHandle(false, EventResetMode.ManualReset, notifyEventName, out createdEvent);

多个进程创建此事件(例如,它在它们之间共享)。它用于在更新内容时发出通知。

我希望能够设置此事件,以便所有等待它的进程都收到信号,然后立即重置它,以便阻止后续等待该事件。

如果我做一个

notifyEvent.Set();
notifyEvent.Reset();

它有时会通知所有监听进程。

如果我做一个

notifyEvent.Set();
Thread.Sleep(0);
notifyEvent.Reset();

更多进程得到通知(我假设这会发生,因为调度程序有机会运行)。

如果我这样做

notifyEvent.Set();
Thread.Sleep(100);
notifyEvent.Reset();

然后一切似乎都很顺利,所有进程(例如 ~8)都会得到一致的通知。我不喜欢在 Sleep 调用中使用“魔数(Magic Number)”。

有没有更好的方法来通知其他进程中的操作系统事件的所有监听器事件已经发生,以便在通知时监听它的每个人都收到事件信号,然后立即重置事件,以便其他人知道去监听事件会阻塞吗?

更新:信号量似乎不太适合这里,因为事件的监听器数量会随时间变化。当事件需要被通知时,事先并不知道会有多少听众。

最佳答案

我遇到了同样的问题,令人惊讶的是在网络上找不到任何好的解决方案来解决这种松散耦合/即发即忘/多监听器类型的事件,所以这就是我想出的办法。

请注意,Set()Reset() 调用之间存在超时的解决方案也存在竞争条件问题(除了它依赖于任意超时值这一事实之外): 如果发布者在这些调用之间被杀死,那么所有的听众将永远看到事件设置(除非发布者再次上线)。

所以要求是:

  • 只有一个发布者(虽然它并没有真正在代码中强制执行)
  • 可以有任意数量的监听器(在同一进程或其他进程中),介于 0 和 N 之间(编译二进制文件后 N 是固定的)。
  • 听众可以随心所欲地来来去去,而不会打扰发布者
  • 发布者可以随心所欲地来来去去,而不会打扰听众

诀窍是使用 AutoReset 事件,因为它们没有竞争条件问题,但为每个监听器定义一个。我们事先不知道听众的数量,但我们可以固定最大听众数量(上面描述的“N”):

const int MAX_EVENT_LISTENERS = 10;
const string EVENT_NAME = "myEvent_";

这是向所有潜在听众引发事件的发布者代码:

public static void RaiseEvent()
{
for (int i = 0; i < MAX_EVENT_LISTENERS; i++)
{
EventWaitHandle evt;
if (EventWaitHandle.TryOpenExisting(EVENT_NAME + i, out evt))
{
evt.Set();
evt.Dispose();
}
}
}

这是获取事件通知的监听器代码:

...
EventWaitHandle evt = GetEvent();
do
{
bool b = evt.WaitOne();
// event was set!
}
while (true);
....

// create our own event that no other listener has
public static EventWaitHandle GetEvent()
{
for (int i = 0; i < MAX_EVENT_LISTENERS; i++)
{
bool createdNew;
EventWaitHandle evt = new EventWaitHandle(false, EventResetMode.AutoReset, EVENT_NAME + i, out createdNew);
if (createdNew)
return evt;

evt.Dispose();
}
throw new Exception("Increase MAX_EVENT_LISTENERS");
}

关于c# - 正确通知系统范围内命名的手动重置事件的所有监听器,然后立即重置它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/429692/

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