2012-07-18 89 views
5

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

服务:

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应该始终有一个手柄,不应该被垃圾收集器收集得到;

+0

所以,你确实是得到FileNotFoundException异常? – 2012-07-18 18:10:19

+0

表单是否与服务位于同一个目录下?有时服务的默认目录是c:\ windows \ system32我会尝试指定文件的完整路径,而不是像“AuditStream”这样的相对路径 – 2012-07-18 18:11:03

+1

服务在哪个帐户下运行? – HABO 2012-07-18 18:22:35

回答

13

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

您必须在mmf名称前面加上Global\以创建并访问全局名称空间中的对象。

所以在服务:

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

和形式:

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

谢谢你做到了!现在我只需要在这个问题上与Access拒绝错误搏斗。 – Zholen 2012-07-18 18:32:30

+0

我想添加任何其他人查看这篇文章,也不要忘记对你的互斥体(“全球”)也这样做,你很可能会遇到访问问题,一旦你可以看到流是以下方式修复它,但它确实使它非常'开放': – Zholen 2012-07-18 19:16:21

+8

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 2012-07-18 19:16:32