可观察(和可取消)循环

时间:2018-04-22 07:25:48

标签: c# .net multithreading observable system.reactive

我正在创建一个模拟器。仿真的核心在这样的无限循环中运行:

while (true) 
{
      UpdateMachineState();
}

我想介绍Reactive Extensions 将此循环执行到另一个线程并使其可取消,但我完全丢失了。

由于我的模拟器是一个GUI应用程序(通用Windows),我不想阻止UI线程。

应该看起来像:

...
while (true) 
{
      if (machine.IsHalted) 
      {
          observer.OnCompleted;
      }

      observer.OnNext(machine.GetState());           
      cancellationToken.ThrowIfCancellationRequested();
}
...

当模拟器进入"停止&#34>时,创建的序列最终会完成。州。否则,它将继续推动States(一个代表其内部状态的对象)。

我已尝试使用Observable.Create,但提供CancellationToken的重载需要Task<Action>

我希望你能弄清楚这个场景。 提前谢谢!

1 个答案:

答案 0 :(得分:3)

以下是您在Rx中的表现方式:

void Main()
{
    var scheduler = new EventLoopScheduler();
    var loop = scheduler.Schedule(a =>
    {
        UpdateMachineState();
        a();
    });

    Thread.Sleep(1);

    loop.Dispose();
}

public void UpdateMachineState()
{
    Console.Write(".");
}

我使用的.Schedule上的重载需要Action<Action>作为参数。如果你想重新安排动作,你只需调用内部动作 - 所以上面的代码有效地创建了无限循环。

然后,您从.Dispose()调用返回时调用.Schedule取消循环。

另一种方法是使用.Generate运算符:

var scheduler = new EventLoopScheduler();
var query =
    Observable
        .Generate(0, x => true, x => x, x => machine.GetState(), scheduler);

var subscription = query.Subscribe(x => Console.Write("."));

Thread.Sleep(1);

subscription.Dispose();