重做EventWaitHandle以异步等待信号 [英] Rework EventWaitHandle to asynchronously await signal

查看:198
本文介绍了重做EventWaitHandle以异步等待信号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

调用EventWaitHandle.WaitOne时,我需要更改当前代码以不阻塞当前线程.问题是我正在等待系统范围的事件.我还没有找到合适的替代品.

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.

代码:

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(" ");
        }

我需要应用程序继续运行,而不是在我调用WaitOne的行上停止,理想情况下会等待.我该如何实现呢?

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 ?

推荐答案

您可以在我的 AsyncEx库中使用AsyncFactory.FromWaitHandle :

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

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

该实现使用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;
}

这篇关于重做EventWaitHandle以异步等待信号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆