MemoryMappedFile.CreateOrOpen 抛出句柄无效

本文关键字:句柄 无效 CreateOrOpen MemoryMappedFile | 更新日期: 2023-09-27 18:31:29

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

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 中,在 64 位 Windows 2008 Server 上运行在 CruiseControl.NET 下,其服务在域帐户(不是本地计算机帐户)下运行。 我可以在登录到同一台机器时手动运行这些相同的测试,它们都通过了。

我知道这些信息可能不足以让某人直接解决,但我甚至不知道如何调查这个问题。 在尝试创建或打开内存映射文件时,哪些类型的内容会导致"句柄无效"消息?

MemoryMappedFile.CreateOrOpen 抛出句柄无效

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

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

因此,选择一个好的随机名称以避免此错误。 可以从Visual Studio获取一个:工具+创建GUID,选项4。 它是全球独一无二的。