【问题标题】:Built in background-scheduling system in .NET?在.NET 中内置后台调度系统?
【发布时间】:2010-06-02 13:25:16
【问题描述】:

尽管我怀疑是否有这样的系统,但我还是问了。

基本上,我需要安排任务在未来某个时间点执行(通常不超过几秒或几分钟后),并且有某种方式取消该请求,除非为时已晚。

即。看起来像这样的代码:

var x = Scheduler.Schedule(() => SomethingSomething(), TimeSpan.FromSeconds(5));
...
x.Dispose(); // cancels the request

.NET 中有这样的系统吗? TPL 中有什么可以帮助我的吗?

我需要在这里从系统中的各种实例运行这样的未来动作,并且宁愿避免每个这样的类实例都有自己的线程并处理它。

另请注意,我不想要这个(或类似的,例如通过任务):

new Thread(new ThreadStart(() =>
{
    Thread.Sleep(5000);
    SomethingSomething();
})).Start();

可能会有一些这样的任务要执行,它们不需要以任何特定的顺序执行,除非接近截止日期,而且它们具有像实时性能概念这样的东西并不重要。我只是想避免为每个此类操作创建一个单独的线程。

【问题讨论】:

    标签: .net .net-4.0 multithreading scheduling task-parallel-library


    【解决方案1】:

    由于您不想有外部参考,您可能需要查看System.Threading.TimerSystem.Timers.Timer。请注意,这些类在技术上与 WinForms Timer 组件有很大不同。

    【讨论】:

    • 启动多个这样的计时器会产生多个线程吗?还是他们使用一些通用的调度线程来处理所有事情?
    • 他们使用线程池线程来执行回调并且没有任何额外的管理线程AFAIR。至少他们肯定没有专用线程。实际的调度是由运行时实现的,应该非常高效,尤其是对于System.Threading.Timer
    【解决方案2】:

    使用quartz.net(开源)。

    【讨论】:

    • 我当然会调查,但不幸的是这是一个类库,我不能有任何外部引用。如果没有内置任何东西,我将不得不自己制作一些东西。谢天谢地,我在这方面的需求很小。
    【解决方案3】:

    嗯.....实际上你可以完全按照你的要求去做......

      IDisposable kill = null;
    
      kill = Scheduler.TaskPool.Schedule(() => DoSomething(), dueTime);
    
      kill.Dispose();
    

    使用我们在 Microsoft 的朋友提供的 Rx Reactive Framework :)

    Rx 非常棒。我几乎用它替换了事件。简直太好吃了……

    嗨,我是 Rusty,我是 Rx 瘾君子……我喜欢它。

    【讨论】:

      【解决方案4】:

      虽然没有明确内置于 .NET,但您是否考虑过编写可以通过 Windows 计划任务进行计划的 EXE?如果您使用的是 .NET,那么您可能会使用 Windows,这不正是计划任务的用途吗?

      我不知道如何将计划任务集成到 .NET 解决方案中,但您当然可以编写从计划任务中调用的组件。

      【讨论】:

      • 这不是一个选项。这里会有很多轻量级的任务要执行。
      【解决方案5】:

      如果您愿意使用 .NET 4,那么新的 System.Threading.Tasks 提供了一种为任务创建自定义调度程序的方法。我没有仔细研究它,但似乎您可以派生自己的调度程序并让它按照您认为合适的方式运行任务。

      【讨论】:

        【解决方案6】:

        除了提供的答案之外,这也可以通过线程池来完成:

        public static RegisteredWaitHandle Schedule(Action action, TimeSpan dueTime)
        {
            var handle = new ManualResetEvent(false);
            return ThreadPool.RegisterWaitForSingleObject(
                                                 handle, 
                                                 (s, t) =>
                                                 {
                                                     action();
                                                     handle.Dispose();
                                                 }, 
                                                 null, 
                                                 (int) dueTime.TotalMilliseconds, true);
        }
        

        RegisteredWaitHandle 有一个Unregister 方法可以用来取消请求

        【讨论】:

          猜你喜欢
          • 2019-01-13
          • 1970-01-01
          • 1970-01-01
          • 2017-08-24
          • 2023-04-01
          • 2012-05-03
          • 2010-12-08
          • 2022-01-24
          • 2014-01-14
          相关资源
          最近更新 更多