C# 如何使Rx回调在线程池上运行?

C# 如何使Rx回调在线程池上运行?,c#,multithreading,system.reactive,rx.net,C#,Multithreading,System.reactive,Rx.net,你会认为下面的程序打印错误吗 输出: 错误的 我不理解的是,该应用程序旨在安排线程池上的工作,但显然不是这样。它的名称可能是指Rx内部的其他线程池,而不是System.Threading命名空间中的实际类 我曾多次尝试强制回调在线程池上运行,但都没有成功。我尝试过的一些事情: .ObserveOn(Scheduler.Default) 上面最后一次尝试是在阅读了微软论坛上的问题之后。不管我怎么做,属性总是返回false 我是否应该编写自己的isScheduler实现来确保代码在线程池上运行?对

你会认为下面的程序打印错误吗

输出:

错误的 我不理解的是,该应用程序旨在安排线程池上的工作,但显然不是这样。它的名称可能是指Rx内部的其他线程池,而不是System.Threading命名空间中的实际类

我曾多次尝试强制回调在线程池上运行,但都没有成功。我尝试过的一些事情:

.ObserveOn(Scheduler.Default)
上面最后一次尝试是在阅读了微软论坛上的问题之后。不管我怎么做,属性总是返回false

我是否应该编写自己的isScheduler实现来确保代码在线程池上运行?对于这样一个微不足道的目标来说,这听起来是一项相当重要的任务


.NET 5.0.1,System.Reactive 5.0.0,C 9

您共享的链接实际上有一个解决方案:

var modScheduler = ThreadPoolScheduler.Instance.DisableOptimizations(new[] { typeof(ISchedulerLongRunning) });
Observable
    .Return(1)
    .ObserveOn(modScheduler)
    .Select(_ => Thread.CurrentThread)
    .Subscribe(t => Console.WriteLine(t.IsThreadPoolThread));

如果查看的源代码,您将看到所有工作都被发送到线程池,ScheduleLongRunning除外。如果禁用该优化,则所有工作都将发送到线程池。

您共享的链接实际上有一个解决方案:

var modScheduler = ThreadPoolScheduler.Instance.DisableOptimizations(new[] { typeof(ISchedulerLongRunning) });
Observable
    .Return(1)
    .ObserveOn(modScheduler)
    .Select(_ => Thread.CurrentThread)
    .Subscribe(t => Console.WriteLine(t.IsThreadPoolThread));

如果查看的源代码,您将看到所有工作都被发送到线程池,ScheduleLongRunning除外。如果禁用该优化,则所有工作都将发送到线程池。

太棒了!我没有意识到DisableOptimizations方法有一个返回值。我希望它会配置/修改现有的调度程序!因此,单线解决方案是.ObserveOnThreadPoolScheduler.Instance.DisableOptimizations非常好!我没有意识到DisableOptimizations方法有一个返回值。我希望它会配置/修改现有的调度程序!因此,单线解决方案是.ObserveOnThreadPoolScheduler.Instance.DisableOptimizations
.ObserveOn(TaskPoolScheduler.Default)
.ObserveOn(new TaskPoolScheduler(Task.Factory))
.ObserveOn(new TaskPoolScheduler(new TaskFactory(TaskScheduler.Default)))
ThreadPoolScheduler.Instance.DisableOptimizations(); // At the start of the program
var modScheduler = ThreadPoolScheduler.Instance.DisableOptimizations(new[] { typeof(ISchedulerLongRunning) });
Observable
    .Return(1)
    .ObserveOn(modScheduler)
    .Select(_ => Thread.CurrentThread)
    .Subscribe(t => Console.WriteLine(t.IsThreadPoolThread));