C# .NET是否可以在进程之间共享大型内存收集?

C# .NET是否可以在进程之间共享大型内存收集?,c#,.net-4.0,ipc,shared-memory,C#,.net 4.0,Ipc,Shared Memory,我有一个控制台应用程序,每天运行一百次,从大文件中读取相同的数据(比如50个文件,总大小为3-4GB) 我正在考虑制作一个Windows服务,它将数据缓存在内存中,以加快访问速度,并控制数据的生命周期(因为这50个文件的集合可能每天都不同) 我将实现共享内存映射文件,这样控制台应用程序将从服务写入的内存中读取文件 然而,还有另一个考虑因素。每次读取的数据都会转换为.NET对象 所以我的问题是-有没有办法在内存中共享而不是文件.NET对象(列表)? 另外,数据是手动序列化的字节序列 有没有办法在内

我有一个控制台应用程序,每天运行一百次,从大文件中读取相同的数据(比如50个文件,总大小为3-4GB)

我正在考虑制作一个Windows服务,它将数据缓存在内存中,以加快访问速度,并控制数据的生命周期(因为这50个文件的集合可能每天都不同)

我将实现共享内存映射文件,这样控制台应用程序将从服务写入的内存中读取文件

然而,还有另一个考虑因素。每次读取的数据都会转换为.NET对象

所以我的问题是-有没有办法在内存中共享而不是文件.NET对象(列表)?

另外,数据是手动序列化的字节序列

有没有办法在内存中共享的不是文件而是.NET对象(列表)

挑剔-不,不可能,分配的对象在特定进程上

您可以使用远程处理之类的东西,但基本上可以在进程之间封送访问

您可以共享非托管空间(共享内存),但不能包含.NET对象-需要编组到这些空间中。

  • 如果你每天都要运行这个应用程序一百次,并且你正在寻找一种将“数据”保存在内存中的方法,为什么不让应用程序继续运行,而不是关闭它,然后重新启动它

  • 您可以创建一个windows服务,将文件加载到内存中并对其进行细化。当然,如果停止或重新启动服务,则需要重新加载数据

  • 另一个解决方案是,与其将对象保存在内存中(只能使用.Remoting或类似的方法来实现),不如将文件导入数据库,这样可以加快进程,并且可以方便地在进程之间共享


据我所知,您不能在多个.NET进程之间直接共享集合,但必须跨进程边界封送数据。这会产生相当大的CPU开销,并且会消耗缓存进程和客户端中对象的内存

使用内存映射文件可能可以实现更好的效果,但这仍然不允许您在共享内存上直接映射.NET对象-但是您说“数据是手动序列化的字节序列”,所以这可能足够合适


我并不十分奇怪,本机代码中的一个伟大之处在于,您只需将文件视为内存指针,而对于.NET MMF,您需要调用访问器方法,从而将内存复制到.NET对象中(?)。。。但它的性能可能比一遍又一遍地读取文件要好。

我只是将其实现为一个提供套接字服务器的服务,让console exe直接连接到该服务并通过TCP/IP发出请求,然后返回响应。非常容易设置,因为您已经(根据问题)对序列化进行了排序,并且非常可扩展。然后,该服务可以在内存中让所有内容都愉快地运行。你甚至可以让客户端和服务器是同一个exe,只要在它开始决定是客户端还是服务器时检查Environment.UserInteractive即可


需要注意的一点是:保持低带宽,避免使用健谈的API;意思是:不要让客户做很多思考,然后提出200个请求;只需将整个请求打包并发送到服务器即可。让服务器在本地解决这些问题,避免大量网络流量。

请参阅TomTom的答案。作为一种变通方法,如果它适合您的需求,您可以创建一个服务来管理数据并对该数据执行逻辑。如果只是简单地搜索或聚合,那么。。。。。您的控制台应用程序只需调用服务中的一个方法并处理该方法的结果。内存为3-4 GB?真正地哎哟,这很伤脑筋。@Polity-如果可以的话,我就不会为映射文件等麻烦了。逻辑本身每天改变100次。数据是静态的。这就是为什么我会按照我解释的方式做事…@Steve远不止这些。但我准备运行子集(作为回报,我将减少运行时间),因为我的应用程序只有4Gb可用。3-4Gb对于我们中的一些人来说很小。我有一些.net应用程序在内存中使用两位数的缓冲区(1015GB)。例如,当您跟踪金融工具的价格(比如,200.000)并获得一些更新(比如每秒25.000次)时,将内容保存在内存中是唯一的解决方案。您将数据写入光盘,但将数据当前状态保留在内存中。这正是我要做的。阅读以下问题:“我将实现共享内存映射文件”…Marc。你应该把这个问题读得更好。我已经有了解决方案映射的内存文件。我想知道是否有一种方法可以映射对象而不是文件。。。你的想法并没有真正的帮助-我仍然需要从字节中反序列化数百万个对象。。您还知道命名管道比tcp更快吗?那么你的意思是什么?@Bobb是的,你有一个解决办法;不止一个。你问的是托管对象,没有:你不能这样做(你必须做你现在正在做的事情);然而,我回答的要点很简单“换一种方式。如果你的问题不合适,那很好——但我对你的设置不太了解,所以请不要嘲笑我。重新命名管道;好的在我所看到的大多数类似的场景中,我们也会为此使用中心节点,因此通过网络,因此是套接字。如果都是本地的,那就太好了!啊-是和否。文件是,但不是其中的对象。海报上已经谈到了mem映射文件,问题是对于一个文件,每次读取时都必须将其来回封送到结构或对象中。它们不提供与gc共享类实例的方法,所有这些都是关于分片对象的。共享数据空间-是。不同的问题。