简体   繁体   中英

c# thread sleep on DataReceived event

I wrote this code on c#

public  class SerialClass 
{
    SerialPort s;
    public Serial()
    {
        InitSerialPort();
        s.DataReceived += dataReciver;

    }

    private void dataReciver(object sender, SerialDataReceivedEventArgs e)
    {
      lock (obj) 
    {
          while (s.BytesToRead >0)
           {
               var line = s.ReadLine();
               if(line=="hello")
               {
                   Thread.Sleep(500);
                   s.WriteLine("hello to you friend");
              }
              else  //......
        }       
           }
    }

}

When i got "hello" from the serial I want to answer after 500 milliseconds "hello to you friend".

I heard so much , don't use sleep on you code..

What is the disadvantage here to use sleep? If more data will get on serialport so new event will enter to dataReciver because it will be open on secondery thread.

so what is the disadvantage and what is the better/best way to implement it without sleep?

I use lock because I want only 1 thread will be on this reading

If you've done it right, you shouldn't need the lock.

IMHO, you should avoid the DataReceived event altogether. Wrap SerialPort.BaseStream in a StreamReader , then loop in an async method to read. Regardless, I also would not put the delay, asynchronous or otherwise, in sequence with your reading. You should always be ready to read.

You didn't provide real code, so it's impossible to offer a real code solution, but here's how I'd have written the bit of code you posted:

public class Serial
{
    SerialPort s;

    public Serial()
    {
        InitSerialPort();

        // Ignore returned task...constructors shouldn't wait. You could store
        // the task in a class field, to provide a mechanism to observe the
        // receiving state.
        Task task = ReceiveLoopAsync();
    }

    private async Task ReceiveLoopAsync()
    {
        using (StreamWriter writer = new StreamWriter(s.BaseStream))
        using (StreamReader reader = new StreamReader(s.BaseStream))
        {
            string line;

            while ((line = reader.ReadLineAsync()) != null)
            {
                if (line == "hello")
                {
                    // Ignore returned task...we don't really care when it finishes
                    Task task = RespondAsync(writer);
                }
            }
        }
    }

    private async Task RespondAsync(StreamWriter writer)
    {
        await Task.Delay(500);
        writer.WriteLine("hello to you friend");
    }
}

I've left out niceties like exception handling and more robust handling of the tasks. But the above is the basic idea. Note that all receiving is done in a single loop, with no need for cross-thread synchronization.

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