等待使用IObserver接口和AutoEventHandler / TaskCompletionSource的事件

时间:2015-07-01 01:14:36

标签: c# multithreading events async-await observer-pattern

在我的场景中,我正在实现一个IObserver接口,以通过方法轮询特定变量的更新。我有一个线程只是为了执行这个方法而创建的。现在这个线程永远不应该退出寻找某些数据的更新。

public static void findUpdates()
{
    while(true)
    {
        CheckForUpdates(); //registered to the observer
    }
}

然后我有多个线程进入类方法来接收更新。

TaskCompletionSource<bool>updateHappened = new TaskCompletionSource<bool>();
object updatedValue;

public async Task receiveUpdates(){

    while(true)
    {
        await updateHappened.Task;
        //check to see if the thread cares about the updated value or not
        //update or do not update and possibly terminate
    }

}

并在OnNext实现中

public void OnNext(Object value){
    updatedHappened.SetResult(true);
}

我需要等待一个事件的原因是因为当我有线程进入我的while()循环是receiveUpdates如果他们没有等待,那么最终可以调度的最大线程数和一些线程被阻止执行直到另一个退出。

现在这种行为不正常,我永远无法通过await updateHappened.Task;无论我创建和发送多少个线程来接收更新。

我希望有能力让想要接收更新的线程通过,挂起线程池中的执行等待执行,以便其他线程(无论多少)也可以尝试接收更新,然后当更新发生时每个线程一次一个,并在再次暂停之​​前更新或不更新。一个线程将始终使用IObserver接口轮询更新,但尝试接收更新的每个其他线程将始终继续查找更新,除非它在条件下退出。

1 个答案:

答案 0 :(得分:2)

TaskCompletionSource<T>只能完成一次;它是一个单发信号,就是这样。

由于您已经在使用Rx,因此请考虑让源线程使用PublishConnect / RefCount公开其可观察对象。这将允许多个订户接收相同的数据。然后,对于只想await的线程,请使用await sequence.FirstAsync()