Ich habe geschrieben, was ich hoffe, ist eine leichte Alternative zur Verwendung der ManualResetEvent und AutoResetEvent-Klassen in C# /. NET. Der Grund dafür war eine Event-ähnliche Funktionalität ohne die Verwendung eines Kernel-Sperrobjekts.Leichte Alternative zu Manual/AutoResetEvent in C#
Obwohl der Code sowohl im Test als auch in der Produktion gut zu funktionieren scheint, kann es eine schwierige Aufgabe sein, diese Art von Ding für alle Möglichkeiten in Ordnung zu bringen und demnächst konstruktive Kommentare und Kritik von StackOverflow zu erbitten. Hoffentlich (nach Überprüfung) wird dies für andere nützlich sein.
Die Verwendung sollte ähnlich wie die Manual/AutoResetEvent-Klassen sein, wobei Notify() für Set() verwendet wird.
Hier geht:
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);
}
}
}
Haben gebenchmarkt Sie diese gegen Manual/AutoResetEvents mit? Wie wichtig ist der Leistungsunterschied? – James
Nein, ich habe noch nicht, da das primäre Ziel war, eine Nicht-Kernel-Handle/Ressource mit Event-Objekt zu machen. Ich werde versuchen, einige Tests einzurichten, danke. – sweetlilmre
Die Implementierung eigener Threading-Primitive ähnelt der Implementierung eigener Krypto-Algorithmen. Wenn Sie kein Experte in der Domäne sind, werden Sie es vermasseln. Selbst wenn Sie ein Experte sind, können Sie es immer noch vermasseln. Tu es nicht. .NET 4 hat sowieso schon "leichte" Versionen, "ManualResetEventSlim" und verwandte Klassen. – Aaronaught