我已经编写了我希望是在 C#/.NET 中使用 ManualResetEvent 和 AutoResetEvent 类的轻量级替代方法。这背后的原因是在没有使用内核锁定对象的情况下拥有类似事件的功能。
虽然代码似乎在测试和生产中都运行良好,但让这种事情适用于所有可能性可能是一项艰巨的任务,我会谦虚地请求 StackOverflow 人群对此提出任何建设性意见和/或批评。希望(经过审查)这对其他人有用。
用法应类似于 Manual/AutoResetEvent 类,其中 Notify() 用于 Set()。
这里是:
using System;
using System.Threading;
public class Signal
{
private readonly object _lock = new object();
private readonly bool _autoResetSignal;
private bool _notified;
public Signal()
: this(false, false)
{
}
public Signal(bool initialState, bool autoReset)
{
_autoResetSignal = autoReset;
_notified = initialState;
}
public virtual void Notify()
{
lock (_lock)
{
// first time?
if (!_notified)
{
// set the flag
_notified = true;
// unblock a thread which is waiting on this signal
Monitor.Pulse(_lock);
}
}
}
public void Wait()
{
Wait(Timeout.Infinite);
}
public virtual bool Wait(int milliseconds)
{
lock (_lock)
{
bool ret = true;
// this check needs to be inside the lock otherwise you can get nailed
// with a race condition where the notify thread sets the flag AFTER
// the waiting thread has checked it and acquires the lock and does the
// pulse before the Monitor.Wait below - when this happens the caller
// will wait forever as he "just missed" the only pulse which is ever
// going to happen
if (!_notified)
{
ret = Monitor.Wait(_lock, milliseconds);
}
if (_autoResetSignal)
{
_notified = false;
}
return (ret);
}
}
}
最佳答案
这是基于 Win32 事件代价高昂的假设。他们不是,我认为没有什么比举办事件更便宜的了。 .NET 设计者决定使用 Win32 事件来实现 MRE 和 ARE 是一个好主意,这就是一个重要的暗示。
更换的真正成本是当您遇到线程竞争并且不知道是什么原因导致的时候,您将遇到的主要 FUD。
关于c# - C# 中 Manual/AutoResetEvent 的轻量级替代品,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2816903/