【问题标题】:Cold observable's Scheduler.CurrentThread - in which thread will it run?Cold observable 的 Scheduler.CurrentThread - 它会在哪个线程中运行?
【发布时间】:2018-08-01 14:17:21
【问题描述】:

我是 RX 新手,开始了解一些概念。我在网上没有找到。

我在我的代码中使用了一个计时器:

Observable.Timer(TimeSpan.FromSeconds(2), schedulerProvider.CurrentThread);
// where schedulerProvider.CurrentThread is actually Scheduler.CurrentThread

我了解 Timer 是一个Cold Observable,每个订阅者都会获得其私人计时器,该计时器将在订阅时运行 2 秒。

我在 thread1 中创建了那个冷的 observable 并使用 thread2 [,thread3 订阅它,thread4 等等...]

所以问题是:它将在哪个线程中运行?

请提供来源。

谢谢!

编辑:感谢您的详细回答。现在我知道我的问题有问题。作为第二个参数传递的调度程序是 NOT 用于订阅者调度,但用于运行计时器。 默认情况下,大多数 RX 运算符在同一线程上运行,但 Timer 是(几个)异常之一。默认情况下,计时器本身将在线程池上运行,并在同一线程上调用 OnNext。如果您要求它使用 CurrentThread 调度程序,计时器本身将在同一个线程上运行(就像大多数 Rx 运算符一样),并且订阅者将在同一个线程上被调用。 (虽然对于常规用例,这不是很推荐)。

【问题讨论】:

    标签: c# .net system.reactive


    【解决方案1】:

    为什么不做一些测试来找出答案?

    这就是我所做的:

    Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
    
    Observable
        .Timer(TimeSpan.FromSeconds(2.0), Scheduler.CurrentThread)
        .Subscribe(x => Console.WriteLine(Thread.CurrentThread.ManagedThreadId));
    

    生产者:

    12 12

    然后我尝试了这个:

    Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
    
    Observable
        .Timer(TimeSpan.FromSeconds(2.0))
        .Subscribe(x => Console.WriteLine(Thread.CurrentThread.ManagedThreadId));
    

    生产出来的:

    12 13
    Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
    
    Observable
        .Timer(TimeSpan.FromSeconds(2.0))
        .ObserveOn(Scheduler.CurrentThread)
        .Subscribe(x => Console.WriteLine(Thread.CurrentThread.ManagedThreadId));
    

    生产出来的:

    11 27

    所有这一切都归结为Scheduler.CurrentThread 捕获当前线程上下文在评估Scheduler.CurrentThread 参数时

    在第一个代码块中在创建计时器时捕获 - 换句话说,我的控制台线程。

    在最后一个块中,它是在计时器触发后捕获的,因此它捕获了计时器触发的线程。

    【讨论】:

    • 对不起,我的回复晚了,我很忙,我喜欢你的回答,我觉得这里缺少一些东西,你对我很有帮助,但我正在等我验证你的答案。谢谢。
    • 谢谢,现在我完全理解了它是如何工作的。但我不同意您的部分解释:在第一个代码块中,它是在创建计时器时捕获的 - 换句话说,我的控制台线程。我认为这是错误的,因为Observable.Timer() 文档:返回一个可观察序列,该序列在指定的相对到期时间过去后产生单个值,使用指定的调度程序运行计时器所以第一个示例在控制台线程中运行 Timer,然后自然地在同一线程上调用 OnNext()
    • 请编辑您的答案以反映该次要修复 =]
    • @Yitzchak - 感谢您的反馈,但我确实将“在创建计时器时”的答案与“使用指定的调度程序运行计时器”相同。你能解释一下为什么你会看到不同吗?
    • 其实你是对的,只是我的问题错了,我已经编辑过了。谢谢(你在很多情况下给了我很多答案)
    猜你喜欢
    • 1970-01-01
    • 2014-08-13
    • 1970-01-01
    • 1970-01-01
    • 2016-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多