如何使web应用程序中的内存映射文件对所有线程可见

本文关键字:线程 文件 映射 web 何使 应用程序 内存 | 更新日期: 2023-09-27 17:49:15

我有以下代码,这是Memory-Map文件的入口点,换句话说,这是对服务器的第一个请求,它将输入字符串写入MM文件,以便以后可以对其他请求使用:

    internal string SetInput(string input)
    {
        try
        {
            MemoryMappedFile mmFile = MemoryMappedFile.CreateOrOpen("Map",2048,MemoryMappedFileAccess.ReadWrite);
            using (MemoryMappedViewStream vStream = mmFile.CreateViewStream())
            {
                BinaryWriter bw = new BinaryWriter(vStream);
                bw.Write(input);
            }
            Logger.AddEntry(Logger.Level.Inf, input);
        }
        catch (Exception e)
        {
            Logger.AddEntry(input, e);
            return "W";
        }
    }

现在,我将以下代码用于其他请求,以便它们可以读取第一个请求发送的内容:

private bool GetInput()
    {
        try
        {
            using (MemoryMappedFile mmFile = MemoryMappedFile.OpenExisting("Map"))
            {
                using (MemoryMappedViewStream stream = mmFile.CreateViewStream())
                {
                    BinaryReader reader = new BinaryReader(stream);
                    string s = reader.ReadString();
                    try
                    {
                        // Do sth
                    }
                    catch (Exception e)
                    {
                        Logger.AddEntry(s, e);
                        return false;
                    }
                }
            }
        }
        catch (IOException e)
        {
            Logger.AddEntry(e);
            return false;
        }
        return true;
    }

但是当最后一个函数试图打开MM文件时,它会得到一个IOException: file not found.

我做错了什么,我认为MM文件在。net中作为共享内存机制工作,或者我在我的代码中缺少一些东西?

如何使web应用程序中的内存映射文件对所有线程可见

在没有看到SetInputGetInput如何被调用的情况下,我必须做一些假设。

是否同步GetInputSetInput的呼叫?如果在第一个请求完成创建之前,传入了一个请求,而您试图映射到指定的区域,那么就会出现问题。您可能需要创建一个共享互斥锁来同步对文件的访问。

同样,根据你处理web请求的方式,处理第一个请求的进程可能在第二个请求到来的时候已经死亡,这将释放第一次调用MemoryMappedFile.CreateOrOpen所持有的句柄,导致操作系统释放文件。数据不会被持久化,因为文件系统不支持该文件。

尝试创建一个文件系统支持的共享内存区域,使用CreateFromFile,看看是否仍然存在问题。


我质疑你直接使用共享内存。我对你的项目一无所知,但还有其他机制可以实现IPC。根据您的具体情况,您可能会发现一个更容易使用的DBMS(即使是像sqlite这样的小DBMS)。

如果这是你想要的消息传递,也有很多现有的选项可以减轻你在这种情况下的痛苦。看这个问题,还有这个。