了解Reactive Extensions和CallContext

时间:2016-08-05 13:19:16

标签: .net system.reactive

我有使用CallContext将会话信息传输到任务延续的代码。现在我已经介绍了Reactive Extensions的使用,并且我观察了一些我想要理解的奇怪行为。

我有这个辅助类,它包含了CallContext的使用。

public static class TestContext
{
    private static readonly string _KEY = "my-context";

    public static int Value
    {
        get { return CallContext.LogicalGetData(_KEY) as int? ?? -1; }
        set { CallContext.LogicalSetData(_KEY, value); }
    }
}

在我的main函数中,我使用interval创建一个cold observable。在每个刻度上,我投影上下文值以查看管道中存在的上下文。

var periodic = Observable.Interval(TimeSpan.FromMilliseconds(100), Scheduler.Default)
    .Select(_ => TestContext.Value)
    .Timestamp();

在循环中,我将上下文设置为循环索引,然后使用LINQPad的DumpLatest方法订阅并转储序列。为了好玩,我在迭代结束时将上下文设置为不同的值(42)。

for (int i = 0; i < 3; i++)
{
    TestContext.Value = i;
    periodic
        .DumpLatest(string.Format("Iteration {0}", i));
    TestContext.Value = 42;
}

我希望每个订阅都能从订阅时间捕获上下文。我希望订阅通知与订阅迭代号匹配。

当我的调度程序是Scheduler.Default时,这完全符合预期,如上面编码的那样。

With Scheduler.Default

但是,如果我将调度程序更改为new EventLoopScheduler(),则所有订阅都使用相同的上下文。

var periodic = Observable.Interval(TimeSpan.FromMilliseconds(100), new EventLoopScheduler())
    .Select(_ => TestContext.Value)
    .Timestamp();

With EventLoopScheduler

为什么Scheduler.Default会按照我的预期传播CallContext,而EventLoopScheduler却没有?

谢谢, Ranj

0 个答案:

没有答案