【问题标题】:Trouble reading from Memory Mapped File从内存映射文件读取时出现问题
【发布时间】:2012-07-17 20:31:21
【问题描述】:

我正在尝试在我的应用程序(特别是 Windows 服务)中实现内存映射文件,然后使用 C# 表单从服务写入的 MMF 中读取。不幸的是,我似乎无法让表单从 MMF 中读取任何内容,更重要的是,表单似乎从未找到由服务创建的 MMF。下面是概述我在做什么的代码 sn-ps,任何人都可以看到我做错了什么或能够为我指出更好的方向吗?

服务:

private MemoryMappedFile mmf = MemoryMappedFile.CreateOrOpen("AuditStream", 1024 * 1024);
private Mutex mutex = new Mutex(false, "MyMutex");

byte[] msg = new byte[1];
var view = mmf.CreateViewStream(0, 1);
byte[] rmsg = new byte[1];

for (int i = 0; i < 400; i++)
{
     mutex.WaitOne();
     for (int j = 0; j < msg.Length; j++)
     {
          msg[j] = (byte)i;
     }

     view.Position = 0;
     view.Write(msg, 0, bufferSize);

     //the next 3 lines verify that i wrote to the mmf and can potentially read from it
     //These are just for testing
     view.Position = 0;
     view.Read(rmsg, 0, 1);
     Log.Error("Finished MMF", rmsg[0].ToString());

     mutex.ReleaseMutex();
 }

表格:

private MemoryMappedFile mmf;
private Mutex mutex;
Thread t = new Thread(MmfMonitor);
t.Start();

private void MmfMonitor()
    {

        byte[] message = new byte[1];
        while(!quit)
        {
            try
            {
                **mmf = MemoryMappedFile.OpenExisting("AuditStream");**
                mutex = Mutex.OpenExisting("MyMutex");
                var view = mmf.CreateViewStream(0, 1);

                mutex.WaitOne();
                view.Position = 0;
                view.Read(message, 0, 1);
                Invoke(new UpdateLabelCallback(UpdateLabel), message[0].ToString());
                mutex.ReleaseMutex();
            }catch(FileNotFoundException)
            {
                **//The AuditStream MMF is never found, and therefore doesnt every see the proper values**
            }
        }
    }

此外,当服务“运行”时,MMF 应该始终有句柄并且不应该被垃圾收集器收集;

【问题讨论】:

  • 那么,您确实得到了 FileNotFoundException 吗?
  • 表单exe是否与服务在同一目录下?有时服务的默认目录是 c:\windows\system32 我会尝试指定文件的完整路径,而不是像“AuditStream”这样的相对路径
  • 运行服务的帐号是什么?
  • @ Peter - 是的,我得到一个 FileNotFoundException,并且没有表单与服务位于同一目录中,因为它是一个完全独立的项目。由于这是共享内存空间而不是特定文件,因此除了名称之外没有“路径”
  • @HABO,如果是权限问题,我希望访问被拒绝异常......

标签: c# ipc shared-memory


【解决方案1】:

服务在另一个会话中运行,即著名的“会话 0”。 Windows 对象位于与进程会话关联的命名空间中,因此您的表单无法看到在服务使用的会话中创建的对象。

您必须在 mmf 名称前添加 Global\ 才能在全局命名空间中创建和访问对象。

所以在服务中:

mmf = MemoryMappedFile.CreateOrOpen(@"Global\AuditStream", ...)

形式:

mmf = MemoryMappedFile.OpenExisting(@"Global\AuditStream");

【讨论】:

  • 谢谢你这样做!,现在我只需要努力解决访问被拒绝的错误。
  • 我想为任何查看此帖子的其他人添加,不要忘记对您的互斥锁(“Global”)也做同样的事情,一旦您看到,您很可能会遇到访问问题以下流是修复它的一种方法,尽管它确实让它非常“开放”:
  • var security = new MemoryMappedFileSecurity(); security.AddAccessRule(new AccessRule("everyone", MemoryMappedFileRights.FullControl, AccessControlType.Allow)); mmf = MemoryMappedFile.CreateOrOpen(@"Global\AmToteAuditStream", 1024 * 1024, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages,security, HandleInheritability.Inheritable);
  • @Zholen 您的上一条评论修复了拒绝访问异常?
猜你喜欢
  • 1970-01-01
  • 2016-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-06
  • 1970-01-01
相关资源
最近更新 更多