我编写了一个类,该类具有一个TProperty
类型的属性和一个Action<TProperty>
类型的事件,只要该属性发生更改,该事件就会触发。 TProperty
通常是枚举类型,但这无关紧要。
我想创建一个带有签名的方法
bool WaitUntilPropertyIs(int TimeoutMs, IEnumerable<TProperty> AllowedValues)
会阻止调用它的线程,直到属性更改为
AllowedValues
中的值为止。当然,如果在属性已经为AllowedValues
之一时调用WaitUntilPropertyIs,则不应进行阻塞。 WaitUntilPropertyIs
最多应等待TimeoutMs
,如果超过了超时,则返回false(正常的AutoResetEvent.Wait
语义)。我愿意使用Reactive Extensions或传统的同步结构。
最佳答案
在这种情况下,Rx显得过分杀伤力。您可以通过ManualResetEvent
或ManualResetEventSlim
进行操作。您可以根据以下方式来设计解决方案:
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;
}
}
不过,我不知道您的确切要求,因此请考虑修改上面的代码以防止出现竞争情况。