.net 基于消息的多线程或线程池,用于短而不常见的操作?

xuo3flqw  于 2022-11-19  发布在  .NET
关注(0)|答案(7)|浏览(140)

我目前在.NET中使用Retlang进行基于消息的多线程处理,这是一个很棒的库。我不再有显式锁,每个线程都在做自己的事情,管理应用程序中属于自己的部分,并通过消息与其他线程通信。
我现在必须实现我的应用程序的一个特性,它也可以有自己的发布者/订阅者线程。唯一的问题是这个线程实际上做的工作很少。它应该每10分钟左右从发布者那里接收一条消息。当收到消息时,它会做一些工作,但不会超过几百毫秒。
所以我开始考虑让线程99.9%的时间处于休眠状态是否是个好的选择。有一个线程池可以进行这种操作,但是由于我无法控制哪个线程会接收我的消息,所以我不得不求助于丑陋的、容易出错的锁。
我的问题是:从资源Angular 看,让线程空闲,等待绝大部分时间,这真的是一个问题吗?在使用了一个良好的基于消息的体系结构之后,使用共享多线程感觉就像回到了过去,而且它将是应用程序中唯一带锁的部分。但是我一直在想,“我在这里做错了什么吗?”

编辑:谢谢大家,在阅读了你们的每一个答案之后,我认为另一个线程并不是一个大问题。我的应用程序将只与基于消息的多线程保持一致,如果我真的有性能问题(但不应该是这种情况),我将进一步调查。

zf2sa74q

zf2sa74q1#

实际上,我认为将ThreadPool用于大部分时间处于休眠状态的线程是一个糟糕的设计选择-
让一个线程休眠(或者更好的是等待一个事件)在你的应用程序中的开销非常小。使用专用线程的主要缺点是线程需要分配自己的堆栈,所以你会使用一点额外的内存,而不是线程池线程。

r1wp621o

r1wp621o2#

这听起来像是使用Task的理想场景。他们默认使用下面的线程池,但有一个更进化的API。

hxzsmxv2

hxzsmxv23#

你不能用Retlang的PoolFiber来实现吗?它没有像ThreadFiber这样的专用线程支持,而是由.Net线程池支持。这意味着你可以在整个应用程序中使用相同的Retlang语义,而不用保留一个空闲线程。

eivgtgni

eivgtgni4#

虽然PoolFiber上的每个Action都可以在单独的池线程中执行,但特定PoolFiber的操作按顺序执行,而不是并行执行,一次只能执行一个池线程。
PoolFiber应该做你正在寻找的事情。

fsi0uk1n

fsi0uk1n5#

我认为这根本上是一个优化问题。你的应用程序有性能问题(特别是内存问题)吗?如果没有,那就继续让线程空闲,让你的代码更干净。一旦你有了真实的的原因,就探索其他的选择。

v64noz0r

v64noz0r6#

我会说,有一个专门的线程来接收这些消息很好。我甚至可以说,这将是首选的方法。这并不像你只是随便创建线程或类似的东西。我们在这里谈论的是一个额外的线程,它不会消耗很多资源(也许有一点堆栈空间)。在我看来,不用担心共享状态的额外同步(当然除了消息传递)的优点胜过缺点。

kiz8lqtg

kiz8lqtg7#

您应该考虑使用F#。它非常适合在不消耗线程的情况下对逻辑单线程代理进行编程(例如,代理可以在ThreadPool中跳跃,但仍然以序列化的方式响应消息,并且到达其邮箱的消息会唤醒它们并调度ThreadPool的工作)。
Link

相关问题