2012-07-18 101 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