ManualResetEvent vs. Thread.Sleep

Ich habe den folgenden Hintergrundverarbeitungs-Thread implementiert, in demJobs ist einQueue<T>:

static void WorkThread()
{
    while (working)
    {
        var job;

        lock (Jobs)
        {
            if (Jobs.Count > 0)
                job = Jobs.Dequeue();
        }

        if (job == null)
        {
            Thread.Sleep(1);
        }
        else
        {
            // [snip]: Process job.
        }
    }
}

Dies führte zu einer merklichen Verzögerung zwischen der Eingabe der Jobs und dem tatsächlichen Start der Ausführung (es werden mehrere Jobs gleichzeitig eingegeben, und jeder Job ist nur [relativ] klein.) Die Verzögerung war kein großes Problem. Aber ich musste über das Problem nachdenken und nahm die folgende Änderung vor:

static ManualResetEvent _workerWait = new ManualResetEvent(false);
// ...
    if (job == null)
    {
        lock (_workerWait)
        {
            _workerWait.Reset();
        }
        _workerWait.WaitOne();
    }

Wo der Thread, der Jobs hinzufügt, jetzt sperrt_workerWait und ruft_workerWait.Set() Wenn das Hinzufügen von Jobs abgeschlossen ist. Diese Lösung beginnt (scheinbar) sofort mit der Verarbeitung von Aufträgen, und die Verzögerung ist insgesamt beseitigt.

Meine Frage lautet zum Teil "Warum passiert das?", Vorausgesetzt, dassThread.Sleep(int) kann sehr gut länger schlafen als du angibst, und teilweise "wie geht das?ManualResetEvent dieses Leistungsniveau erreichen? "

BEARBEITEN: Da jemand nach der Funktion gefragt hat, die Elemente in die Warteschlange stellt, ist dies hier, zusammen mit dem vollständigen System, wie es im Moment ist.

public void RunTriggers(string data)
{
    lock (this.SyncRoot)
    {
        this.Triggers.Sort((a, b) => { return a.Priority - b.Priority; });

        foreach (Trigger trigger in this.Triggers)
        {
            lock (Jobs)
            {
                Jobs.Enqueue(new TriggerData(this, trigger, data));
                _workerWait.Set();
            }
        }
    }
}

static private ManualResetEvent _workerWait = new ManualResetEvent(false);
static void WorkThread()
{
    while (working)
    {
        TriggerData job = null;

        lock (Jobs)
        {
            if (Jobs.Count > 0)
                job = Jobs.Dequeue();

            if (job == null)
            {
                _workerWait.Reset();
            }
        }

        if (job == null)
            _workerWait.WaitOne();
        else
        {
            try
            {
                foreach (Match m in job.Trigger.Regex.Matches(job.Data))
                    job.Trigger.Value.Action(job.World, m);
            }
            catch (Exception ex)
            {
                job.World.SendLineToClient("\r\n\x1B[32m -- {0} in trigger ({1}): {2}\x1B[m",
                    ex.GetType().ToString(), job.Trigger.Name, ex.Message);
            }
        }
    }
}

Antworten auf die Frage(2)

Ihre Antwort auf die Frage