在这行代码上,我得到了一个System.OutOfMemoryException
异常:
mutex2 = new Mutex(true, "Name2");
以下是堆栈跟踪信息:
{"Exception of type 'System.OutOfMemoryException' was thrown."}
at Microsoft.Win32.Win32Native.CreateMutex(SECURITY_ATTRIBUTES lpSecurityAttributes, Boolean initialOwner, String name)
at System.Threading.Mutex.CreateMutexHandle(Boolean initiallyOwned, String name, SECURITY_ATTRIBUTES securityAttribute, SafeWaitHandle& mutexHandle)
at System.Threading.Mutex.MutexTryCodeHelper.MutexTryCode(Object userData)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.Mutex.CreateMutexWithGuaranteedCleanup(Boolean initiallyOwned, String name, Boolean& createdNew, SECURITY_ATTRIBUTES secAttrs)
at System.Threading.Mutex..ctor(Boolean initiallyOwned, String name, Boolean& createdNew, MutexSecurity mutexSecurity)
at System.Threading.Mutex..ctor(Boolean initiallyOwned, String name)
at Foo.FooDefinitions.FooManager.FooForm.FooForm_Load(Object sender, EventArgs e) in c:\tfs\DWS\TRUNK\DEV\FooDefinitions\FooManager\FooForm.cs:line 92
只有在我使用模拟身份时才会发生这种情况。如果不使用模拟身份(在我的普通Windows帐户上运行),它将正常运行。模拟身份的示例如下:
if (!NativeMethods.LogonUser(userName, domainName, password, 2, 0, ref this._tokenHandle)) // [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
this._impersonatedUser = new WindowsIdentity(this._tokenHandle).Impersonate();
编辑: 为了详细说明,我正在对旧代码创建自动化测试。如果可能的话,我会删除对互斥锁的使用。我目前正在调查 Mutex 构造函数中的 SecurityCriticalAttribute。
编辑2: 这里是完整的代码示例:
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.ComponentModel;
using System.Net;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Threading;
namespace ReinierDG.MutexTesting
{
[TestClass]
public class MutexTest
{
[TestMethod]
public void CreateMutexUnderImpersonation()
{
var credentials = new NetworkCredential("testagent", "secretpassword");
var tokenHandle = new IntPtr();
if (!NativeMethods.LogonUser(credentials.UserName, credentials.Domain, credentials.Password, 2, 0, ref tokenHandle))
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
var impersonatedUser = new WindowsIdentity(tokenHandle).Impersonate();
// this will run indefinately or untill memory is full with 1 cpu core at 100%
var mutex = new Mutex(true, "test");
}
internal static class NativeMethods
{
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern bool LogonUser([MarshalAs(UnmanagedType.LPWStr)]string lpszUsername, [MarshalAs(UnmanagedType.LPWStr)]string lpszDomain, [MarshalAs(UnmanagedType.LPWStr)]string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
}
}
}
CreateMutex
在一个while(true)
循环内,也许你发现了一个无限循环的错误吗? - QuanticFooForm.FooForm_Load
方法的代码 - giamminMutex(bool, string)
来创建命名互斥量。请参见此处 - 使用Mutex(bool, string, out bool)
代替。你确定需要一个命名的Mutex
吗? - Bastian Thiede