简体   繁体   中英

ManualResetEvent(EventWaitHandle) Set spends much cpu than WaitOne(timeout)

While implementing ManualResetEvent something surprised me,

As far as I understand mre.Set() command signals and let other processes to execute.

mre.WaitOne(); Holds on the current line and waits for a signal. Beside this if we use it with timeout mre.WaitOne(100ms);

BUT! Lets suppose that StartCommunicate is a thread's job.

If I use waitHandle.Set(); my process uses ~%25 or for another project ~%1 CPU resource.

But if I use waitHandle.WaitOne(100); (the timeout value is symbolic. It (try)waits for a signal for 100ms).

The process starts using ~%0 CPU resource with waitone(timeout) What does it mean ? ThereIsAJobToExecute is Socket.HasData for me. So does it mean that hitting much to SerialPort.BytesToRead or Socket.Available makes our CPU usage higher ?

Does it any side effect for me holding the thread for 100 ms for every hit? Supposing that a socket program or a rs232 connection baud rate is very low comparatively new generation PCs.

So using mre.WaitOne(1); seems more preferable to me. What do you think about it ? I'm doing some experiments with some memory and performance profilers but I'm not sure if I'm doing optimum solution for various kind of client machines or not...

Longing for your comments.

Thanks in advance!

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

    }

EDIT: For Socket programming it is available to work ASYN so we can easily do it by the below code and we don't need polling.

But RS232 COMM port programming I need it. Or not ?

 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();
     }

WaitOne puts the thread in a suspended state, which does not cost CPU resources. The signal from the ManualResetEvent later awakens the thread.

It's not 100% clear to me what you're using the ManualResetEvent for. However...

Doing something like waitHandle.WaitOne(1) is pretty much pointless, as you're sleeping for such a small amount of time that you're effectivly busy waiting on that thread, and consuming CPU resources that are not doing anything.

If you're looking to tell your thread that it should wake up and process data then try something like this:

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

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

This will put your thread to sleep when there is nothing to do, and it won't waste any resources. Now you can signal it with waitHandle.Set() when there is work to do.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM