【问题标题】:Writing my own IScheduler to to manage threads, what should be the best way to do this?编写我自己的 IScheduler 来管理线程,最好的方法是什么?
【发布时间】:2013-09-08 08:16:22
【问题描述】:

我正在使用 ReactiveUI 的 ReactiveCommand 功能,它非常酷并且可以达到目的。我遇到的唯一问题是,实例化时的 ReactiveCommand 需要一个 IScheduler 实现,目前它只提供两个 MainThreadScheduler 和 TaskPoolScheduler 并且它们都允许为每个 ReactiveCommand 实例创建单独的线程,这是我无法承受的,因为我的应用程序有大量的 ReactiveCommand 实例.

所以我决定拥有自己的 IScheduler 实现,我可以将它传递给 ReactiveCommand 构造函数,我想做的是拥有某种可配置的 MaxThread;这将不允许超过 MaxThread 线程。

我现在可以想到两种方式

  1. 每当应用程序启动时,启动这些线程并将它们置于等待状态以尝试从 ActionBlock 中删除任务,当调用 Schedule 时,将该 Action 对象添加到 ActionBlock 实例中。

  2. Create and Destroy,基本同1,但是一旦任务完成,就结束线程而不是让它保持活动状态。

有人对我们应该如何实现这一点有任何建议吗?任何输入、代码示例、文章链接或 Github/Codeplex 上的任何内容都将不胜感激。

【问题讨论】:

    标签: c# multithreading system.reactive reactive-programming reactiveui


    【解决方案1】:

    如果您不想在默认调度程序上为长时间运行的任务启动新线程,那么您可以使用默认调度程序并禁用 ISchedulerLongRunning 优化,如下所示:

    Scheduler.Default.DisableOptimizations(typeof(ISchedulerLongRunning));
    

    如果您不这样做,ObserveOn 之类的内容将为每个订阅创建一个新线程

    【讨论】:

      【解决方案2】:

      那么你为什么不想使用 DefaultScheduler,它会为你踢出一个线程池呢?

      另外,如果在内部调用ScheduleLongRunning(),你确定这就是你想要的吗?看起来您可能会引入车队和线程争用,这是一个复杂的工作领域。

      也许你实际上想要做的是

      1. 准备好线程池,这样在需要向其中添加线程时就不会出现暂停
      2. 为您的应用程序创建更好的并发设计。如果你有 80 件事情同时安排在 UI 中,那听起来有些不太对劲。

      我想保罗会有一些见解?

      【讨论】:

      • ReactiveCommand 的构造函数导致 ScheduleLongRunning() 调用创建一个新线程并将其置于等待状态。 Grid 的每一行都有 1 个 ReactiveCommand,并且有 40 多行。不仅 ReactiveCommand 的构造函数导致为其操作创建一个新线程,而且还导致一个用于观察异常的线程。所以每个响应式命令有 2 个线程......不,这不是我想要的,因为一旦我的应用程序达到 80 个线程标记,它就会抛出内存不足异常。
      • 可能我应该在多个网格行之间共享一个命令实例,并将行标识信息传递给命令参数或其他东西。
      • 共享单个 Command 实例是很常见的事情,因此在这种情况下可能会很好。我在调用ScheduleLongRunning() 的ReactiveCommand 代码中看不到任何代码,只调用ObserveOn 和ScheduledSubject<T> ctor,然后只调用ObserveOn。 ScheduleLongRunning() 在哪里被调用?
      • 我有 Rx 和 RxUI 代码......我正在引用项目......它在特定于平台的抽象层实现......有一个名为 ScheduledObserver 的内部类,其构造函数正在调用 _longRunning = _scheduler。 AsLongRunning() 基本上是对我的自定义调度程序的扩展,它返回一个新的 ISchedulerLongRunning 实例......你要么必须通过代码;要么没有简单的解释......如果你喜欢我可以给你一个示例应用程序代码。
      • 我当然明白。然而,调用_scheduler.AsLongRunning() 与调用ScheduleLongRunning() 仍然不同。你的IScheduler 的实现* 在调用它时是否在构造一个线程? -->* 你为什么要创建自己的IScheduler?!
      【解决方案3】:

      用.NET的ThreadPool实现IScheduler,轻松设置ThreadPool的最大线程数。

      代码项目上有好几种ThreadPool的实现,没有的可以使用

      对 .NET 的默认应用程序池感兴趣,或者您可能不喜欢在 .NET 中使用 ThreadPool

      这种情况

      如果您在实施 IScheduler 本身时遇到问题,请告诉我。

      祝你好运

      【讨论】:

      • 谢谢 Yasser 我会查找 CodeProject。 .NET ThreadPool 的缺点是什么?,我听到很多人说它不好。
      • 您至少可以提供一些链接来支持您的发现。
      • 我有自己的 IScheduler 只是为了发现 Rx 在内部强制调用 ScheduleLongRunning() 来启动一个新线程,而不管我的调度程序是如何编写的。 :(
      • 我会尽快回复你,但我不在电脑旁)-:我会在 5 小时内用我的答案替换此评论
      • 嗯,已经 13 个小时了。但我感谢你试图帮助我。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-24
      相关资源
      最近更新 更多