我编写了一个类,该类具有一个TProperty类型的属性和一个Action<TProperty>类型的事件,只要该属性发生更改,该事件就会触发。 TProperty通常是枚举类型,但这无关紧要。

我想创建一个带有签名的方法

bool WaitUntilPropertyIs(int TimeoutMs, IEnumerable<TProperty> AllowedValues)


会阻止调用它的线程,直到属性更改为AllowedValues中的值为止。当然,如果在属性已经为AllowedValues之一时调用WaitUntilPropertyIs,则不应进行阻塞。 WaitUntilPropertyIs最多应等待TimeoutMs,如果超过了超时,则返回false(正常的AutoResetEvent.Wait语义)。

我愿意使用Reactive Extensions或传统的同步结构。

最佳答案

在这种情况下,Rx显得过分杀伤力。您可以通过ManualResetEventManualResetEventSlim进行操作。您可以根据以下方式来设计解决方案:

public event Action<TProperty> MyEvent;
public TProperty Prop { get; private set; }

bool WaitUntilPropertyIs(int timeout, IEnumerable<TProperty> allowedValues)
{
    var gotAllowed = new ManualResetEventSlim(false);
    Action<int> handler = item =>
    {
        if (allowedValues.Contains(item)) gotAllowed.Set();
    };

    try
    {
        MyEvent += handler;
        return allowedValues.Contains(Prop) || gotAllowed.Wait(timeout);
    }
    finally
    {
        MyEvent -= handler;
    }
}


不过,我不知道您的确切要求,因此请考虑修改上面的代码以防止出现竞争情况。

07-27 13:59