I have single external resource - named pipe. I need to be able to do the following:
- multiple async tasks can be spawn nearly simultaneously (by EXCEL-DNA function, ran in many cells)
- tasks will try to aquire access to the pipe (there can be only one pipe per app) in arbitrary manner
- the winning task will send request and wait for the response, then release the pipe to next waiting task
- a task waiting for too long should continue after timeout (return "#err" value)
- I am not yet sure whether tasks will be fired from different threads (I am new to excel-dna)
I can't quite figure out an elegant way to do it (one thing comes to mind - a r/w lock with timeout).
Is there a pure async solution for such problem?
It seems like you can use a queue for this, just like Dave suggests in the comments.
With the help of a
TaskCompletionSource<TResult>, you can create your own tasks that you can complete with our own logic.The following is a simple incomplete example (not tested and just typed here) of how you can implement something like this:
In this example I haven't included code how you read the next task from the queue but you start with calling
StartProcessing()so you stop the timeout. If this returns afalse, then this task is already timed out and you can just go to the next item in the queue. Otherwise you do your thing with the pipe, and the result you can set to theCompletion.TrySetResult(), any errors that occured can be set toCompletion.TrySetException().I have included the
TaskCreationOptions.RunContinuationsAsynchronouslybecause otherwise the code that is awaiting thePipeAccess.GetResult()will continue on this thread, making yourPipeAccesswait until that code is done before it can continue to the next queued task (and increasing the likelyhood of a timeout).