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()
когда есть работа