6

アプリケーション (具体的には 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 は常にハンドルを持つ必要があり、ガベージ コレクターによって収集されるべきではありません。

4

1 に答える 1

14

サービスは別のセッション、有名な「セッション 0」で実行されます。Windows オブジェクトは、プロセスのセッションに関連付けられた名前空間に存在するため、サービスによって使用されるセッションで作成されたオブジェクトをフォームから見ることはできません。

Global\グローバル名前空間でオブジェクトを作成してアクセスするには、mmf 名の先頭に追加する必要があります。

したがって、サービスでは:

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

そして次の形式で:

mmf = MemoryMappedFile.OpenExisting(@"Global\AuditStream");
于 2012-07-18T18:26:56.830 に答える