gpt4 book ai didi

c# - 使用模拟时互斥创建挂起

转载 作者:太空狗 更新时间:2023-10-29 22:57:41 25 4
gpt4 key购买 nike

在测试应用程序时,我遇到了奇怪的行为。一些测试使用模拟以不同用户的身份运行代码,但它们总是会挂起,永远不会完成。

经过一些调查,问题缩小到互斥体的使用。最初,我们使用自己的基于 MSDN documentation 的模拟代码, 但即使使用 SimpleImpersonation library问题仍然存在。这是重现问题的最小示例:

using (Impersonation.LogonUser(DOMAIN, USER, PASSWORD, LogonType.Interactive))
{
Console.WriteLine("Impersonated");
bool mine;
using (new Mutex(true, "Mutex", out mine))
{
if (!mine)
throw new Exception("Couldn't get mutex");
Console.WriteLine("Got mutex");
}
}

Console.WriteLine("Finished");

这永远不会结束,它停留在创建互斥量的线上。 documentation声明它应该抛出异常或返回一些东西,但没有提到阻塞。

一些其他观察结果,可能相关也可能不相关:

  • 如果我们“模拟”当前用户,它会立即返回
  • 如果我们运行实际的应用程序并启动另一个实例作为不同的用户,一切都按预期工作

可能底层系统资源正在发生某些事情,但我们无法弄清楚。如何实现?

更新:根据 Hans 的评论,我尝试禁用 Windows Defender,但没有帮助。这是它挂起的地方的堆栈跟踪:

    ntdll.dll!_NtWaitForSingleObject@12()
KernelBase.dll!_WaitForSingleObjectEx@12()
mscorlib.ni.dll!719c1867()
[Frames below may be incorrect and/or missing, native debugger attempting to walk managed call stack]
mscorlib.ni.dll!719c1852()
[Managed to Native Transition]
mscorlib.dll!System.Threading.Mutex.CreateMutexHandle(bool initiallyOwned, string name, Microsoft.Win32.Win32Native.SECURITY_ATTRIBUTES securityAttribute, out Microsoft.Win32.SafeHandles.SafeWaitHandle mutexHandle)
mscorlib.dll!System.Threading.Mutex.MutexTryCodeHelper.MutexTryCode(object userData)
[Native to Managed Transition]
[Managed to Native Transition]
mscorlib.dll!System.Threading.Mutex.CreateMutexWithGuaranteedCleanup(bool initiallyOwned, string name, out bool createdNew, Microsoft.Win32.Win32Native.SECURITY_ATTRIBUTES secAttrs)
mscorlib.dll!System.Threading.Mutex.Mutex(bool initiallyOwned, string name, out bool createdNew, System.Security.AccessControl.MutexSecurity mutexSecurity)
mscorlib.dll!System.Threading.Mutex.Mutex(bool initiallyOwned, string name, out bool createdNew)
MutexImpersonationTest.exe!MutexImpersonationTest.Program.Main(string[] args) Line 16

最佳答案

看起来获取 Mutex 的代码陷入了无限循环,在我的测试中,它在调用 new Mutex(...) 时将一个核心锁定在 100% .

这似乎是框架代码首先尝试调用 Win32 CreateMutex,如果失败并出现“拒绝访问”错误,则尝试调用 OpenMutex .如果 OpenMutex 调用失败并显示错误指示互斥锁不存在,它会再次重复整个过程,因此如果互斥锁不存在则会陷入无限循环。

根据CreateMutex documentation ,这本质上是正确的方法,但似乎没有考虑到初始 CreateMutex 因现有互斥锁的权限而不是的拒绝访问失败的情况.

在我尝试时似乎确实有效的一件事是在互斥锁名称前加上“Global\”前缀,希望这是适合您的解决方法。

关于c# - 使用模拟时互斥创建挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36591765/

25 4 0