1

I am generating an RTP packet each 20ms for each call. Each call is handled upon 'awaiting' my listening server UDPClient.ReceiveAsync.

I am using a high precision timer (using TimeSetEvent from winmm.dll) which fires each 20ms and 'sets' a dedicated ManualResetEventSlim (MRES) object created for each different incoming UDP call. Each time the MRES is set, the call thread is released and a single packet is sent on each call and so on.

Am I wasting threads by keep blocking the thread in no CPU-bound operation while its MRES is not signaled? Is there an 'async' version of this MRES that can await. If yes, would that increase the throttle of my main UDPClient.RececiveAsync loop?

Application is Windows WinForms and another version as Windows Service.

  • You could [try using a `SemaphoreSlim`](https://stackoverflow.com/a/12858633/106159), which *does* have an async wait method. – Matthew Watson Sep 24 '19 at 15:20
  • I think @MatthewWatson is on the right track, but if you show us your code, we can give you more specifics. Also, what kind of app is this? ASP.NET, console, etc.? – Gabriel Luci Sep 24 '19 at 15:29
  • A thread doing stuff 50 times per second is not wasteful. But technically, yes, the timeSetEvent callback already takes a thread. It might as well do whatever that waiting thread does. Also safer, no guarantee that such a thread can see the MRE being set so you might easily miss one or more updates. – Hans Passant Sep 24 '19 at 15:32
  • I tried changing the design to build in advance the complete buffer (ConcurrentQueue) of the complete data in one shot. Then using the tight timer callback to just dequeue packet by packet and I can see significant performance boost. –  Sep 24 '19 at 17:20

1 Answers1

3

Am I wasting threads by keep blocking the thread in no CPU-bound operation while its MRES is not signaled?

Technically, yes. Sometimes, though, "wasting" threads is exactly what you want to do. Specifically, when writing desktop control software with tight timing requirements, blocked threads tend to give more reliable behavior than asynchronous code.

Is there an 'async' version of this MRES that can await.

Yes, there's an AsyncManualResetEvent as part of my AsyncEx library. Or you can build your own. Stephen Toub's build-your-own version is more performant; my AsyncEx version is optimized around maintainability rather than performance.

If yes, would that increase the throttle of my main UDPClient.RececiveAsync loop?

No idea.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810