I am using C#.
I have a UDPServer class with methods called BeginWork and EndWork.
When BeginWork is called, I want it to detect type A work that can be completed immediately, type B work that can be completed after a timeout, and type C work that can be completed when a WaitHandle is set (the wait handle is retrieved from a built in .NET BeginReceive call on a socket.)
I am trying to avoid using an additional thread.
I have a main game server thread that wants to wait for network related work that needs to be done, in which case it would call EndWork, or just wait for its own timeout value to elapse and then call its own Update method.
I would like to have BeginWork return a WaitHandle so that the main thread can call WaitOne or WaitAny, passing in its own timeout.
How can I combine the check for types A, B, and C work into a single WaitHandle that can be returned to the main thread?
A few more details just in case they are helpful:
My UDPServer class is implementing reliable UDP.
The type A work is detecting out of order packets that can now be processed because the in order packets leading up to them were finally received and processed.
The type B work is needing to send ack packets when we have waited long enough to group a few acks, but not so long that the other side will think it needs to resend an unacknowledged packet.
The type C work is just waiting for additional packets to come in.
If I create a MyWaitHandle class to wrap the logic of waiting on the network timeout and receive WaitHandle, then the main thread can not combine that with any other wait handles.
It might work for this particular scenario, but if the main thread ever needs to wait on something else at the same time then it won't work.
I would rather not expose multiple WaitHandles and a timeout value to my caller, because that complicates their logic for something that should be self contained.
They should only need a WaitHandle that they can wait on to know if any work is ready to be done in UDPServer or not.
I might be able to make it work by passing callbacks to BeginReceive and a System.Threading.Timer.
Then having those callbacks set a ManualResetEvent that corresponds to the WaitHandle I return, along with some internal state to note which work is ready.
This does introduce some ThreadPool threads, which is not as bad as me creating a dedicated thread, but the synchronization logic still seems to get hairy.
I guess I wanted something like this to exist:
var waitHandle = WaitHandle.CreateWaitAny(waitHandleArray, timeout);
But then I'd still need to internally determine which of the waitHandles was ready, or if the timeout occurred, so maybe that isn't really the right solution either.
Thanks for any help.