C # language equivalent to ScheduledExecutorService

I am working with an RF reader device having a C # API. Based on its API, you need to manually call its read function to read / skip the map.

So my workaround is to use a timer to read every "n" second.

My problem is that a timer that runs continuously, regardless of Thread.sleep (), triggered an action inside it.

Timer timer = new Timer(TimerCallback, null, 500, 1000); // From main() method // The action that Timer executes private void TimerCallback(Object o) { scan(); // Action for reading/badging card scand.WaitOne(); // AutoResetEvent(true) GC.Collect(); // Force garbage collection } 

Thread.sleep () calls inside scan ().

In Java, I use synchronized () to wait for another thread to invoke invoke (). I searched all day and I don't see a workaround that would be equivalent to ScheduledExecutorService and synchronized ().

Hope this is related to this, I need it as soon as possible.

Thanks!

+5
source share
1 answer

The most reliable way I could find is to restart the timer in the callback. Thus, the callback is not interrupted when active.

 Timer timer = new Timer(TimerCallback, null, 500, 0); private void TimerCallback(Object o) { scan(); scand.WaitOne(); timer.Change(500, 0); } 

timer.Change redistributes the timer.

Note. I removed the repetition while the timer started.

By the way: I deleted GC.Collect() , because in most cases I find this bad practice and useless.

In addition, you can get the time at the beginning of the method (use Stopwatch ) and calculate the required time delta for timer transmission. Edit:

 Timer timer = new Timer(TimerCallback, null, 500, 0); Stopwatch stopwatch = Stopwatch.StartNew(); private void TimerCallback(Object o) { var entered = stopwatch.ElapsedMilliseconds; scan(); scand.WaitOne(); var duration = stopwatch.ElapsedMilliseconds - entered; var delay = Math.Max(0, 500 - duration); timer.Change(delay, 0); } 

Thus, the callback will be called after 500 ms minus the time required to perform the scan functions. Tune in this way and you can remove Sleep from the scan.

The reason for the double callback in your code is probably because the timer is making a callback in another thread when the first thread is still making a callback.

Another solution might not be to use a timer at all. Just cycle and use a stopwatch to calculate the period of time for sleep:

 private void Scan() { while(scanning) { var entered = stopwatch.ElapsedMilliseconds; scan(); scand.WaitOne(); var duration = stopwatch.ElapsedMilliseconds - entered; var delay = Math.Max(0, 500 - duration); Thread.Sleep(delay); } } 

Make sure you call this method in a separate thread (you can use Task)

+2
source

Source: https://habr.com/ru/post/1201831/


All Articles