MemoryMappedFile.CreateOrOpen throws句柄无效

时间:2012-04-17 18:29:39

标签: c# .net memory-mapped-files

我有代码创建一个内存映射文件,如下所示:

using (Mutex mutex = new Mutex(false, CoordinatorMutexName))
{
    mutex.WaitOne();

    var security = new MemoryMappedFileSecurity();
        security.SetAccessRule(
            new AccessRule<MemoryMappedFileRights>(
                new SecurityIdentifier(WellKnownSidType.WorldSid, null), // everyone
                MemoryMappedFileRights.FullControl,
                AccessControlType.Allow));

    MemoryMappedFile coordinator = MemoryMappedFile.CreateOrOpen(
        CoordinatorMMFName,
        16 * 1024 * 1024 + 4,
        MemoryMappedFileAccess.ReadWrite,
        MemoryMappedFileOptions.DelayAllocatePages,
        security,
        HandleInheritability.None);

...
...

}

在某些情况下(如下所述),CreateOrOpen调用会抛出以下异常:

 System.IO.IOException: The handle is invalid.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.MemoryMappedFiles.MemoryMappedFile.CreateOrOpenCore(SafeFileHandle fileHandle, String mapName, HandleInheritability inheritability, MemoryMappedFileSecurity memoryMappedFileSecurity, MemoryMappedFileAccess access, MemoryMappedFileOptions options, Int64 capacity)
   at System.IO.MemoryMappedFiles.MemoryMappedFile.CreateOrOpen(String mapName, Int64 capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options, MemoryMappedFileSecurity memoryMappedFileSecurity, HandleInheritability inheritability)

它只在运行自动化测试时抛出此异常,我无法在本地,调试器内部或外部重现此异常。我尝试将上述代码提取到独立测试中,并且无法重现该问题。但是在这里发布所有内容的代码太多了。 MemoryMappedFile在线程的持续时间内持久化(假设它被创建),然后处理掉。

以下是测试失败的条件:测试旨在从多个线程中运用此代码。它们位于NUnit中,在CruiseControl.NET下运行,其服务在64位Windows 2008 Server上的域帐户(不是本地计算机帐户)下运行。我可以在登录同一台机器时手动运行相同的测试,但它们都通过了。

我知道可能没有足够的信息让某人直接解决,但我甚至不知道如何调查这个问题。在尝试CreateOrOpen内存映射文件时,哪些类型的事情可能导致“句柄无效”消息?

1 个答案:

答案 0 :(得分:3)

创建内存映射文件的底层winapi函数CreateFileMapping()是错误代码:

  

如果lpName与现有事件,信号量,互斥锁,等待计时器或作业对象的名称匹配,则该函数将失败,并且GetLastError函数将返回ERROR_INVALID_HANDLE。发生这种情况是因为这些对象共享相同的命名空间。

所以选择一个好的随机名称来避免这个错误。您可以从Visual Studio中获取一个:工具+创建GUID,选项4.它是全局唯一的。