-1

I know this is a general question. But even after going through different articles, it is still confusing. I have a Windows form application. I read some data from a device through the serial port of the PC. For the proper data transfer, my application has to make frequent wait sometimes. (to make sure that there is no data loss). I tried Thread.Sleep() and realized that my device lost the serial connection many times. I have seen explanations that a Timer is an option but does a Timer freeze the UI as well? Which is the best option in this case ( Sleep or Task.Delay or Timer)?

private static System.Timers.Timer _delayTimer;
private static void delay(int Time_delay)
 {
   int i = 0;          
   _delayTimer = new System.Timers.Timer();
   _delayTimer.Interval = Time_delay;
   _delayTimer.AutoReset = false; 
   _delayTimer.Elapsed += (s, args) => i = 1;
   _delayTimer.Start();
   while (i == 0) { };
}
private async void delayAsync(int delaySec)
{            
    await Task.Delay(vals);   //is it the right way of doing delay ?           
}

d219
  • 2,707
  • 5
  • 31
  • 36
master_yoda
  • 463
  • 3
  • 11
  • 1
    I don't think that either waiting technique are in cause of your serial port connection loss. Can you specify what problem you want to solve between `lost connection technical problem` vs `how to sleep/wait in c# desktop application`? – Jonathan Larouche Nov 19 '19 at 14:54
  • What UI framework do you use? – vernou Nov 19 '19 at 15:05
  • 2
    Instead of asking what the difference between the thread-blocking `Thread.Sleep()` and any of the the asynchronous `Timer` classes (which are functionally equivalent to `Task.Delay()`), you should be asking why you're losing data on the serial port. It may or may not have anything at all to do with delays in your code, and even if it does, adding more delays may or may not be the correct way to fix it. Typically, a modern PC has no trouble keeping up with serial port I/O rates, so it's likely you've got a bigger architectural problem somewhere. – Peter Duniho Nov 19 '19 at 18:37

2 Answers2

1

Thread.Sleep suspends the current thread. Calling it on the UI Thread makes the UI unresponsive - because you're suspending the current thread for the given time.

You can use Task.Delay together with await to perform a logical block without suspending the UI thread. That way your application remains responsive but yet waits for the delay to finish.

devsmn
  • 1,031
  • 12
  • 21
-1

In your example :

private static void delay(int Time_delay)
 {
   int i = 0;          
   _delayTimer = new System.Timers.Timer();
   _delayTimer.Interval = Time_delay;
   _delayTimer.AutoReset = false; 
   _delayTimer.Elapsed += (s, args) => i = 1;
   _delayTimer.Start();
   //This line wait the timer and freeze the UI
   while (i == 0) { };
}

The waiter is in the UI's thread and freeze the UI.

I think, you need asynchronous. If you can use TPL (System.Threading.Task) :

private static async void delay(TimeSpan timeDelay, Action updateUI)
{
   //Wait some time without freeze the UI
   await Task.Delay(timeDelay);
   //Call updateUI on UI's thread
   updateUI();
}
vernou
  • 6,818
  • 5
  • 30
  • 58