I have an Async processing pipeline. I'm implementing a constraint such that I need to limit the number of submissions to the next stage. For my component, I have:
- a single input source (items are tagged with a source id)
- a single destination that I need to propagate the inputs to in a round-robin fashion
If capacity is available for multiple clients, I'll forward a message for each (i.e. if I wake because client 3's semaphore has finally become available, I may first send a message for client 2, then 3, etc)
The processing loop is thus waiting on one or more of the following conditions to continue processing:
- more input has arrived (it might be for a client that is not at its limit)
- capacity has been released for a client that we are holding data for
Ideally, I'd thus use Task.WhenAny
with
- a task representing the input
c.Reader.WaitToReadAsync(ct).AsTask()
- N tasks representing the clients for which we are holding data, but it's not yet valid for submission (the
Wait
for theSemaphoreSlim
would fail)
SemaphoreSlim's AvailableWaitHandle
would be ideal - I want to know when it's available but I don't want to reserve it yet as I have a chain of work to process - I just want to know if one of my trigger conditions has arisen
Is there a way to await
the AvailableWaitHandle
?
My current approach is a hack derived from this answer to a similar question by @usr - posting for reference
My actual code is here - there's also some more detail about the whole problem in my self-answer below