Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rework EventWaitHandle to asynchronously await signal

I need to change current code to not block current thread when EventWaitHandle.WaitOne is called. Problem is that I am awaiting system-wide event. I did not find any proper replacement yet.

Code:

EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.AutoReset, "Local event", out screenLoadedSignalMutexWasCreated);

        StartOtherApp();

        if (screenLoadedSignalMutexWasCreated)
        {
            isOtherAppFullyLoaded = handle.WaitOne(45000, true);

            if (isOtherAppFullyLoaded )
            {
                // do stuff
            }
            else
            {
                // do stuff
            }

            handle.Dispose();
            signalingCompleted = true;
        }
        else
        {
            isOtherAppFullyLoaded = false;
            throw new Exception(" ");
        }

I need app to continue and not stop on the line where I call WaitOne, ideally there would be await. How can I implement this ?

like image 208
frno Avatar asked Jun 09 '14 11:06

frno


1 Answers

You can use AsyncFactory.FromWaitHandle, in my AsyncEx library:

isOtherAppFullyLoaded = await AsyncFactory.FromWaitHandle(handle,
    TimeSpan.FromMilliseconds(45000));

The implementation uses ThreadPool.RegisterWaitForSingleObject:

public static Task<bool> FromWaitHandle(WaitHandle handle, TimeSpan timeout)
{
    // Handle synchronous cases.
    var alreadySignalled = handle.WaitOne(0);
    if (alreadySignalled)
        return Task.FromResult(true);
    if (timeout == TimeSpan.Zero)
        return Task.FromResult(false);

    // Register all asynchronous cases.
    var tcs = new TaskCompletionSource<bool>();
    var threadPoolRegistration = ThreadPool.RegisterWaitForSingleObject(handle,
        (state, timedOut) => ((TaskCompletionSource<bool>)state).TrySetResult(!timedOut),
        tcs, timeout);
    tcs.Task.ContinueWith(_ =>
    {
        threadPoolRegistration.Dispose();
    }, TaskScheduler.Default);
    return tcs.Task;
}
like image 101
Stephen Cleary Avatar answered Nov 15 '22 23:11

Stephen Cleary