C# 使用C语言管理缓冲池#

C# 使用C语言管理缓冲池#,c#,buffer,pool,C#,Buffer,Pool,我们需要为使用C#开发的应用程序开发某种缓冲区管理 本质上,应用程序在设备进入时接收来自设备的消息(在短时间内可能会有很多)。我们需要在某种缓冲池中对它们进行排队,以便我们能够以托管方式处理它们 我们考虑将内存块分配为256字节块(所有消息都小于256字节块),然后使用缓冲池管理来拥有一个可用的缓冲池,用于传入消息和一个准备处理的缓冲池 因此,流将是“获取缓冲区”(处理它)“释放缓冲区”或“将其留在池中”。我们还需要知道缓冲区何时填满 我们可能还需要一种“窥视”缓冲区的方法,以查看池中最高优先级

我们需要为使用C#开发的应用程序开发某种缓冲区管理

本质上,应用程序在设备进入时接收来自设备的消息(在短时间内可能会有很多)。我们需要在某种缓冲池中对它们进行排队,以便我们能够以托管方式处理它们

我们考虑将内存块分配为256字节块(所有消息都小于256字节块),然后使用缓冲池管理来拥有一个可用的缓冲池,用于传入消息和一个准备处理的缓冲池

因此,流将是“获取缓冲区”(处理它)“释放缓冲区”或“将其留在池中”。我们还需要知道缓冲区何时填满

我们可能还需要一种“窥视”缓冲区的方法,以查看池中最高优先级的缓冲区是什么,而不是总是获取下一个缓冲区

NET中是否已经支持这一点,或者是否有一些开源代码可供我们使用?

C#sharps内存管理实际上相当不错,因此,您可以不使用缓冲池,而直接分配所需的内容并将其放入队列中。一旦完成缓冲区的处理,就让垃圾收集器来处理它

另一种选择(对您的应用程序知之甚少)是在收到消息时以最小的速度处理它们,并将它们转换为完整的对象(具有优先级和所有优先级),然后您的队列可以通过调查正确的属性集或方法来对它们进行优先级排序

如果您的消息传入得太快,即使是最小的处理,您也可以使用两个队列系统。一个是未处理的缓冲区队列,下一个队列是从缓冲区构建的消息对象队列


我希望这会有所帮助。

为什么不接收消息,创建一个DeviceMessage(因为没有更好的名称)对象,然后将该对象放入队列中?如果优先级排序很重要,请实现一个PriorityQueue类,该类会自动处理优先级排序(在将DeviceMessage对象插入队列时按优先级顺序放置)。看起来更像是一种面向对象的方法,随着时间的推移,在优先级方面会简化维护。

我也在做类似的事情。我有来自MTA线程的消息,需要在STA线程上进行服务

我使用了一个由多个STA线程(可配置,但默认为xr*核心数)监控的(并行fx扩展的一部分)。每个线程都试图从队列中弹出一条消息。他们要么超时再试一次,要么成功弹出一条消息并为其提供服务

我已经将它与perfmon计数器连接起来,以跟踪空闲时间、作业长度、传入消息等,这些可以用来调整队列的设置

您必须实现自定义集合,或者可能扩展BC,以实现队列项目优先级


我以这种方式实现它的原因之一是,据我所知,通常倾向于单线、多台服务器(为什么我觉得我会对此大惊小怪?)

@greve:Networking是原生的,这意味着当缓冲区用于网络上的接收/发送数据时,它们被固定在内存中。请参阅下面我的评论以了解详细内容。

我知道这是一篇老文章,但我认为您应该看看ILNumerics项目中实现的内存池。我认为他们确实做了你需要的,这是一段非常好的代码。
在下载代码并查看文件ILMemoryPool.cs

不是一个好主意。由于GC必须固定对象,任何与互操作相关的操作都将导致碎片(并导致内存不足异常)。如果nzpcmad在后台使用IOCP(例如,通过调用Socket类的Begin/End pairs或*Async方法),这将导致。因此,共享缓冲区而不是让GC来处理缓冲区可能是一个更好的主意。我猜这也是@Jonathan所说的,Amit的回答是对你关于钉住的直接回应。-1,我相当肯定System.Net命名空间抽象了所有这些,最终用户都远离你,阻止你处理这些。我也没有看到在操作中提到应用程序使用任何类型的互操作。也许我不清楚-网络总是在非管理上下文中发生,这意味着你发送到网络API的缓冲区(无论你喜欢与否,都在本机WINSOCK的末尾…)被固定在内存中,不能被垃圾收集或压缩(在内存中移动)当GC试图压缩堆时。这会导致巨大的内存碎片和性能损失,因为缓冲区可能会保留到第1代(甚至第2代)对GC来说,这将是一件痛苦的事情,尽管您一直在分配更多的缓冲区。正确的方法是创建一个缓冲池,您希望在网络中使用,因此内存会丢失,但会集中在一个地方,不会占用GC开销来管理,并且不会为您已经支付的内存空间分配缓冲区。例如,在以web服务器为例,明智的做法是为正在提供服务的文件提供缓存,将文件缓冲区保留在内存中,并在使用Socket.Send时使用这些缓冲区。-无需分配或惩罚,这些缓冲区在几乎所有实际场景中都会长期有效。直接链接到ILMemoryPool