ManualResetEvent по сравнению с потоком. Сон

Я задаюсь вопросом, как XML сгенерирован, и действительно ли это - действительное сообщение SOAP? Можно отправить его через HTTP, как предложили люди выше.

, Если Вы хотите протестировать, если это собирается работать, можно дать SoapUI попытка (для тестирования, которое я имею в виду).

12
задан Matthew Scharley 12 July 2009 в 22:15
поделиться

2 ответа

События - это примитивы ядра, предоставляемые ОС / ядром, которые предназначены только для такого рода вещей. Ядро обеспечивает границу, на которой вы можете гарантировать атомарные операции, которые важны для синхронизации (некоторая атомарность может быть выполнена и в пользовательском пространстве с поддержкой оборудования).

Короче говоря, когда поток ожидает события, он помещается в список ожидания для этого события и помечается как неработающий. Когда событие сигнализируется, ядро ​​пробуждает тех, кто находится в списке ожидания, и отмечает их как работоспособные, и они могут продолжать работу. Естественно, огромным преимуществом является то, что поток может немедленно просыпаться, когда поступает сигнал о событии, по сравнению со спящим в течение длительного времени и время от времени перепроверять условие.

Даже одна миллисекунда - это действительно очень много времени, вы могли бы обработать тысячи событий за это время. Кроме того, разрешение по времени традиционно составляет 10 мс, поэтому сон менее 10 мс обычно просто приводит к сну 10 мс. С помощью события поток можно разбудить и сразу запланировать

16
ответ дан 2 December 2019 в 05:55
поделиться

Первая блокировка на _workerWait бессмысленна, событие - это системный объект (ядро), предназначенный для передачи сигналов между потоками (и активно используемый в Win32 API для асинхронных операций). Поэтому для нескольких потоков вполне безопасно устанавливать или сбрасывать его без дополнительной синхронизации.

Что касается вашего основного вопроса, вам также необходимо увидеть логику для помещения вещей в очередь и некоторую информацию о том, сколько работы выполнено для каждое задание (тратит ли рабочий поток больше времени на обработку или ожидание работы).

Вероятно, лучшим решением будет использование экземпляра объекта для блокировки и использования Monitor.Pulse и ] Monitor.Wait в качестве переменной условия.

Изменить: с учетом кода для постановки в очередь кажется, что ответ # 1116297 прав: задержка в 1 мс - это слишком долго, чтобы ждать, учитывая, что многие из рабочих элементов будут обрабатываться чрезвычайно быстро.

Подход, предусматривающий наличие механизма для пробуждения рабочего потока, является правильным (поскольку нет параллельной очереди .NET с блокирующая операция удаления из очереди). Однако вместо использования события переменная условия будет немного более эффективной (поскольку в неконкурентных случаях она не требует перехода ядра):

object sync = new Object();
var queue = new Queue<TriggerData>();

public void EnqueueTriggers(IEnumerable<TriggerData> triggers) {
  lock (sync) {
    foreach (var t in triggers) {
      queue.Enqueue(t);
    }
    Monitor.Pulse(sync);  // Use PulseAll if there are multiple worker threads
  }
}

void WorkerThread() {
  while (!exit) {
    TriggerData job = DequeueTrigger();
    // Do work
  }
}

private TriggerData DequeueTrigger() {
  lock (sync) {
    if (queue.Count > 0) {
      return queue.Dequeue();
    }
    while (queue.Count == 0) {
      Monitor.Wait(sync);
    }
    return queue.Dequeue();
  }
}

Monitor.Wait снимет блокировку параметра, дождитесь, пока Pulse () или PulseAll () вызывается против блокировки, затем повторно входит в блокировку и возвращается. Необходимо повторно проверить условие ожидания, потому что какой-то другой поток мог прочитать элемент из очереди.

Подход наличия механизма для пробуждения рабочего потока является правильным (поскольку нет параллельной очереди .NET с блокирующей операцией удаления из очереди). Однако вместо использования события переменная условия будет немного более эффективной (поскольку в неконкурентных случаях она не требует перехода ядра):

object sync = new Object();
var queue = new Queue<TriggerData>();

public void EnqueueTriggers(IEnumerable<TriggerData> triggers) {
  lock (sync) {
    foreach (var t in triggers) {
      queue.Enqueue(t);
    }
    Monitor.Pulse(sync);  // Use PulseAll if there are multiple worker threads
  }
}

void WorkerThread() {
  while (!exit) {
    TriggerData job = DequeueTrigger();
    // Do work
  }
}

private TriggerData DequeueTrigger() {
  lock (sync) {
    if (queue.Count > 0) {
      return queue.Dequeue();
    }
    while (queue.Count == 0) {
      Monitor.Wait(sync);
    }
    return queue.Dequeue();
  }
}

Monitor.Wait снимет блокировку параметра, дождитесь, пока Pulse () или PulseAll () вызывается против блокировки, затем повторно входит в блокировку и возвращается. Необходимо повторно проверить условие ожидания, потому что какой-то другой поток мог прочитать элемент из очереди.

Подход наличия механизма для пробуждения рабочего потока является правильным (поскольку нет параллельной очереди .NET с блокирующей операцией удаления из очереди). Однако вместо использования события переменная условия будет немного более эффективной (поскольку в неконкурентных случаях она не требует перехода ядра):

object sync = new Object();
var queue = new Queue<TriggerData>();

public void EnqueueTriggers(IEnumerable<TriggerData> triggers) {
  lock (sync) {
    foreach (var t in triggers) {
      queue.Enqueue(t);
    }
    Monitor.Pulse(sync);  // Use PulseAll if there are multiple worker threads
  }
}

void WorkerThread() {
  while (!exit) {
    TriggerData job = DequeueTrigger();
    // Do work
  }
}

private TriggerData DequeueTrigger() {
  lock (sync) {
    if (queue.Count > 0) {
      return queue.Dequeue();
    }
    while (queue.Count == 0) {
      Monitor.Wait(sync);
    }
    return queue.Dequeue();
  }
}

Monitor.Wait снимет блокировку параметра, подождите, пока Pulse () или PulseAll () вызывается против блокировки, затем повторно входит в блокировку и возвращается. Необходимо повторно проверить условие ожидания, потому что какой-то другой поток мог прочитать элемент из очереди.

условная переменная будет немного более эффективной (поскольку в неконкурентных случаях она не требует переключения ядра):

object sync = new Object();
var queue = new Queue<TriggerData>();

public void EnqueueTriggers(IEnumerable<TriggerData> triggers) {
  lock (sync) {
    foreach (var t in triggers) {
      queue.Enqueue(t);
    }
    Monitor.Pulse(sync);  // Use PulseAll if there are multiple worker threads
  }
}

void WorkerThread() {
  while (!exit) {
    TriggerData job = DequeueTrigger();
    // Do work
  }
}

private TriggerData DequeueTrigger() {
  lock (sync) {
    if (queue.Count > 0) {
      return queue.Dequeue();
    }
    while (queue.Count == 0) {
      Monitor.Wait(sync);
    }
    return queue.Dequeue();
  }
}

Monitor.Wait снимет блокировку параметра, дождитесь, пока Pulse () или PulseAll () вызывается против блокировки, затем повторно входит в блокировку и возвращается. Необходимо повторно проверить условие ожидания, потому что какой-то другой поток мог прочитать элемент из очереди.

условная переменная будет немного более эффективной (поскольку в неконкурентных случаях она не требует перехода ядра):

object sync = new Object();
var queue = new Queue<TriggerData>();

public void EnqueueTriggers(IEnumerable<TriggerData> triggers) {
  lock (sync) {
    foreach (var t in triggers) {
      queue.Enqueue(t);
    }
    Monitor.Pulse(sync);  // Use PulseAll if there are multiple worker threads
  }
}

void WorkerThread() {
  while (!exit) {
    TriggerData job = DequeueTrigger();
    // Do work
  }
}

private TriggerData DequeueTrigger() {
  lock (sync) {
    if (queue.Count > 0) {
      return queue.Dequeue();
    }
    while (queue.Count == 0) {
      Monitor.Wait(sync);
    }
    return queue.Dequeue();
  }
}

Monitor.Wait снимет блокировку параметра, дождитесь, пока Pulse () или PulseAll () вызывается против блокировки, затем повторно входит в блокировку и возвращается. Необходимо повторно проверить условие ожидания, потому что какой-то другой поток мог прочитать элемент из очереди.

10
ответ дан 2 December 2019 в 05:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: