ManualResetEvent(EventWaitHandle) Set тратит гораздо больше ресурсов процессора, чем WaitOne(тайм-аут)

При реализации ManualResetEvent что-то меня удивило,

Насколько я понимаю mre.Set() сигналы команды и позволяют другим процессам выполняться.

mre.WaitOne(); Держит на текущей строке и ждет сигнала. Кроме того, если мы используем его с таймаутом mre.WaitOne(100ms);

НО! Предположим, что StartCommunicate является работой потока.

Если я использую waitHandle.Set(); мой процесс использует ~%25 или для другого проекта ~%1 ресурс ЦП.

Но если я использую waitHandle.WaitOne(100); (значение тайм-аута является символическим. Он (попытается) ожидает сигнала в течение 100 мс).

Процесс начинает использовать ресурс процессора ~%0 с waitone(тайм-аут) Что это значит? Есть IsAJobToExecute - это Socket.HasData для меня. Означает ли это, что сильное попадание в SerialPort.BytesToRead или Socket.Available увеличивает загрузку нашего процессора?

Есть ли побочный эффект для меня, удерживая нить в течение 100 мс для каждого удара? Предположим, что программа сокетов или скорость соединения RS232 очень низка по сравнению с ПК нового поколения.

Итак, используя mre.WaitOne(1); кажется более предпочтительным для меня. Что вы думаете об этом? Я провожу некоторые эксперименты с некоторыми профилями памяти и производительности, но я не уверен, что я делаю оптимальное решение для различных типов клиентских машин или нет...

Тоска по вашим комментариям.

Заранее спасибо!

    ManualResetEvent waitHandle = new ManualResetEvent(false);
    public void StartCommunicate()
    {
        while (true)
        {
            if (ThereIsAJobToExecute)
            {
                Execute the job here!
            }
            else {
                //waitHandle.Set();
                waitHandle.WaitOne(1);
            }                              
        }

    }

РЕДАКТИРОВАТЬ: Для программирования Socket это доступно для работы ASYN поэтому мы можем легко сделать это с помощью приведенного ниже кода, и нам не нужен опрос.

Но программирование порта RS232 мне нужно. Или нет?

 do
 {
      socket.BeginReceiveASYN(....ReceiveCallBack,...,socket)
      mre.WaitOne();
      mre.Reset();
 }while(true)

     void ReceiveCallBack(IResult rst)
     {
     //get the socket and do my job here!
      mre.Set();
     }

2 ответа

WaitOne переводит поток в состояние ожидания, что не требует ресурсов процессора. Сигнал от ManualResetEvent позже пробуждает нить.

Мне не на 100% ясно, что вы используете ManualResetEvent за. Тем не мение...

Делать что-то вроде waitHandle.WaitOne(1) это в значительной степени бессмысленно, поскольку вы спите в течение такого небольшого количества времени, что вы эффективно заняты, ожидая в этом потоке и потребляя ресурсы ЦП, которые ничего не делают.

Если вы хотите сообщить вашему потоку, что он должен проснуться и обработать данные, попробуйте что-то вроде этого:

while(true)
{
  waitHandle.Wait();
  waitHandle.Reset();

  while(ThereIsAJobToExecute)
  {
    // Process the jobs
  }
}

Это уложит ваш поток в спящий режим, когда нечего делать, и не будет тратить впустую ресурсы. Теперь вы можете сигнализировать это с waitHandle.Set() когда есть работа

Другие вопросы по тегам