【问题标题】:Equivalent of Objective-C Dispatch Queues in C# .NET approach or idiom等效于 C# .NET 方法或习语中的 Objective-C 调度队列
【发布时间】:2017-07-08 01:15:33
【问题描述】:

我是 C# .Net 世界的新手,我正在创建一个 .NET API 服务,该服务写入执行全表锁定的 MS Access 数据库表,最多有 20 人同时写入表(我们正在摆脱 Access,但还不够快!)。我们需要确保“作家”不会被锁定。

虽然线程解决方案适用于大多数语言,但 Apple 建议使用 Dispatch Queues 来支持上述并发挑战(请参阅下面的摘录),其中对共享资源的请求一次排队并处理一个以避免冲突。

C#中是否有等效的方法或习语?

我确实看到了this SO 问题,但在我需要的正确上下文中它并没有真正得到答案。

更多详情:

Excerpt from Dispatch Queues Objective-C docs:

调度队列是一种基于 C 的机制,用于执行自定义任务。调度队列以串行或并行方式执行任务,但始终以先进先出的顺序执行。 (换句话说,调度队列总是按照它们被添加到队列中的相同顺序出队和启动任务。)串行调度队列一次只运行一个任务,等到该任务完成后再出队并开始一个新的一个。相比之下,并发调度队列会启动尽可能多的任务,而无需等待已经启动的任务完成。

调度队列还有其他好处:

它们提供了一个简单明了的编程接口。他们 提供自动和整体的线程池管理。他们提供 调谐组装速度。它们的内存效率更高(因为 线程堆栈不会停留在应用程序内存中)。他们不陷阱 到负载下的内核。将任务异步分派到 调度队列不能死锁队列。它们在下面优雅地缩放 争论。串行调度队列提供了一种更有效的替代方案 锁和其他同步原语。

您提交到调度队列的任务必须封装在函数或块对象中

编辑: 事实证明,.Net“主循环”或主线程是您可以请求处理代码的地方。主循环是所有 UI 工作通常完成的地方。根据这个SO问题The Windows GUI Main Loop in C#...where is it?你也可以通过Application.RunTimer访问它

【问题讨论】:

  • 因为大多数时候调度队列的顺序保证是无用的,你可以只使用基本上存在于所有语言中的线程池——它们启动起来会更有效率。如果您需要顺序调度,您通常会进行 GUI 工作,在这种情况下,您的框架会提供正确的工具(例如 WPF/WinForms 的调度程序)。对于您自己需要这种行为的罕见情况,一个简单的阻塞队列或类似的就可以了,但我会质疑设计。
  • 谢谢@Voo,让我看看这些选项。

标签: c# objective-c .net multithreading synchronization


【解决方案1】:

我发现您的问题很有趣,并且与我可以使用更多知识的 .NET 框架领域相关,因此我对该主题进行了一些研究。给你:

有几个与友好管理线程相关的 .NET 选项可能有助于您尝试执行的操作。突出的是TaskScheduler.QueueTaskThreadPool.QueueUserWorkItemBackgroundWorker 也可能适用于您在架构上不受欢迎的情况。

TaskSchedulerThreadPool 任务/线程队列的文档均未提及对排队项目顺序的任何保证。如果线程任务的顺序非常重要,基于我对 .NET 框架的公认有限知识,您可能希望使用队列启动器方法来保证自己排队,该方法接受写入请求并写入数据库或将写入排队直到写入权限可用。这会有点混乱,因为您需要锁定并发。来自similar SO questiongithub hosted code 可能对此有好处。我没有测试过。

或者,您可以使用SetMaxThreads 将写入任务排队到一次限制为一个线程的线程池中。我不能保证这是否适合你的情况,或者永远,尽管它看起来很简单。

希望有帮助

编辑: 对类似 SO 问题的进一步研究,由原始问题发布者指出,Concurrent Queue,新的 .NET 4.0,确保处理 ConcurrentQueue 排队任务中的​​下一个任务,而无需额外的并发锁定代码。使用了Queue。这种方法将尽可能允许同时执行多个任务,而不是像单线程处理器线程池方法那样总是等待前一个任务完成。

【讨论】:

  • 谢谢@stackuser83,这东西有点毛茸茸,所以我想看看它有什么意义。
  • 我绝对需要最后的胜利。 @stackuser83, your SO reference 带我去ConcurrentQueue 需要调查!!
  • 如果我将线程队列限制为 1,QueueUserWorkItem 也可以工作,但 ConcurrentQueue 是最优雅的。如果您可以将其纳入您的答案,我会接受您的答案!
  • 哎呀@stackuser83,抱歉我迟到了。我错过了通知。
猜你喜欢
  • 1970-01-01
  • 2013-03-14
  • 2012-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多