如何使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中作为共享内存机制工作,或者我在我的代码中缺少一些东西?
在没有看到SetInput
或GetInput
如何被调用的情况下,我必须做一些假设。
是否同步GetInput
和SetInput
的呼叫?如果在第一个请求完成创建之前,传入了一个请求,而您试图映射到指定的区域,那么就会出现问题。您可能需要创建一个共享互斥锁来同步对文件的访问。
同样,根据你处理web请求的方式,处理第一个请求的进程可能在第二个请求到来的时候已经死亡,这将释放第一次调用MemoryMappedFile.CreateOrOpen
所持有的句柄,导致操作系统释放文件。数据不会被持久化,因为文件系统不支持该文件。
尝试创建一个文件系统支持的共享内存区域,使用CreateFromFile
,看看是否仍然存在问题。
我质疑你直接使用共享内存。我对你的项目一无所知,但还有其他机制可以实现IPC。根据您的具体情况,您可能会发现一个更容易使用的DBMS(即使是像sqlite这样的小DBMS)。
如果这是你想要的消息传递,也有很多现有的选项可以减轻你在这种情况下的痛苦。看这个问题,还有这个。