【问题标题】:How to queue some amount of work so they execute in sequence如何对一些工作进行排队,以便它们按顺序执行
【发布时间】:2012-05-04 10:53:27
【问题描述】:

我有一个任务或工作项队列,需要在后台按顺序执行。这些任务将属于“即发即弃”类型,这意味着一旦它们开始,我真的不在乎它们是否完成,不需要取消或状态更新。如果他们没有完成,用户将能够重试或手动诊断。

目标是能够保持对队列的引用并且只需要这样做

myQueue.Add( () => DoMyStuff() );

为了向队列中添加一些东西。

System.Threading.Task 类似乎只能将任务一个接一个地排队,而不是通过引用一个公共队列。我不想管理获取最新任务并附加到它的复杂性。

线程池不保证顺序并且会并行执行工作项。 (这很棒,但不是我需要的)

是否有任何内置类可以处理我没有想到的?

编辑: 我们需要能够在以后将任务添加到队列中。场景是当用户单击按钮时,我们希望向设备发送命令(例如打开或关闭灯泡)。这些命令需要 5 秒来处理,我们希望用户能够多次单击并将请求排队。我们不知道会有多少任务排队,也不知道任务是什么。

【问题讨论】:

  • 一个BackgoundWorker和一个阻塞集合?
  • 我不完全确定我是否理解:为什么不使用 ConcurrentQueue 单个线程(或可能多个)将只是 myQueue.TryDequeue().Invoke()
  • 有没有办法自动执行插入到阻塞集合中的最新任务?我可以推出自己的排队/出队/执行机制,但我真的不想重新发明轮子,而且这似乎很常见,以至于已经存在解决方案。
  • IIRC,你可以让 BlockingCollection 表现得像一个堆栈而不是一个队列。

标签: c# .net multithreading


【解决方案1】:

创建BlockingCollection,默认使用ConcurrentQueue作为其内部数据结构。确保任何具有先决条件的任务首先将其先决条件添加到集合中。 BlockingCollection 可以是 Tasks 的集合,一些自定义项表示要调用的方法的参数,Func<>Action<> 要执行,或者其他。我个人会选择TaskAction

然后你只需要一个线程来遍历集合中的每个项目并同步执行它们。

您可以在队列工作时将新项目添加到队列中,不会有任何问题。

【讨论】:

    【解决方案2】:

    如何同时启动所有线程并让它们监听作业完成事件。

    说你的线程按照运行的顺序有id,所有的线程可以同时启动,但是会一直休眠直到他们完成前一个作业的作业/超时

    作业完成/超时事件还将帮助您的监控线程跟踪工作线程

    【讨论】:

    • 如果队列中有100万个任务怎么办?在任何情况下,让线程像这样休眠直到其他线程完成都不是一个好主意。
    • 没错,使用后台工作器和 Martin James 提到的阻塞集合会更有效
    • 老实说,每次我在人们的代码中看到Sleep 时,我都会在内心深处死去。总的来说,这不是对您的评论。为什么让那个可怜的线程只是坐在那里无所事事?几乎总是有更好的设计。
    【解决方案3】:

    您可以创建一个队列对象作为 System.Threading.Task 的包装器。如果你在底层线程池中将并发执行的线程数限制为只有 1 个,我认为你的问题就解决了。

    限制执行任务数量:System.Threading.Tasks - Limit the number of concurrent Tasks

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-18
      • 2014-10-06
      • 2019-04-09
      • 2022-01-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多