mutex .ctor莫名其妙地抛出系统。
我有一个为.NET 4.7.2构建的ASP.NET应用程序,并在IIS下的各种Windows服务器上运行,所有这些服务器都使用相同的应用程序池配置。
最近,我在运行该应用程序的一台服务器上有一个令人惊讶的崩溃错误。在检查Windows事件日志条目后,我看到了一个堆栈跟踪,该跟踪指向system.unauthorizedAccessexception
被System.Threading.mutex
.ctor抛出。错误消息是这样的:
访问路径'00000000-0000-0000-0000-0000-0000000000000000'被拒绝。
这有些令人惊讶,因为所讨论的代码路径常规处理带有GUID名称的静音路径多年来没有任何问题。但是我确实确定了这一点,直到最近,它们都是实际的指导。由于最近的代码更改,现在也有可能将guid.Empty
的字符串值用作MUTEX名称。
自然,我假设Windows OS不喜欢的> 00000000-0000-0000-0000-0000-0000-000000000000
GUID。也许它是保留的,我想自己。
因此,我没有进一步思考,天真地安排了东西,以便将固定的替换GUID值用作MUTEX名称,而不是guid.Empty
。
同样,令我惊讶的是,几天后,我收到了有关 在代码中完全相同的位置遇到的错误的报告! Windows事件日志中的错误消息清楚地说明了新的替换值,这证明了我的天真结论是错误的。
然后,我设计了以下测试,期望在调试器下可以在我的机器上观察到的崩溃:
// Random GUID name.
var random = new Mutex(false, Guid.NewGuid().ToString());
random.WaitOne();
random.ReleaseMutex();
random.Dispose();
// Empty GUID name.
var zero = new Mutex(false, Guid.Empty.ToString());
zero.WaitOne();
zero.ReleaseMutex();
zero.Dispose();
// Prefixed GUID name.
var adorned = new Mutex(false, "SomePrefix-" + Guid.NewGuid().ToString());
adorned.WaitOne();
adorned.ReleaseMutex();
adorned.Dispose();
正如预期的那样,所有三个案例都在调试器下正常工作。我还没有机会在我的ASP.NET应用程序崩溃的实际服务器上测试这些案例,因为...嗯,因为过程。我第二天左右到达那里。
我试图在此期间要回答的问题是:为什么这些值可能在一台特定服务器上不起作用?是配置问题吗?权利问题?关于GUID子字符串的信息?还是完全是其他东西?
I have an ASP.NET app, built for .NET 4.7.2 and running on a variety of Windows servers under IIS, which all use the same App Pool configuration.
I was recently informed about a surprising crashing bug on one of the servers that are running the app. Upon examining the Windows Event Log entries, I saw a stack trace, which pointed to a System.UnauthorizedAccessException
being thrown by a System.Threading.Mutex
.ctor. The error message was this:
Access to the path '00000000-0000-0000-0000-000000000000' is denied.
This was somewhat surprising, because the code path in question had been routinely handling mutexes with GUID names without any problem for years now. But I did determine that up to until recently, they were all actual GUIDs. Due to a recent code change, there is now also the possibility that the string value of Guid.Empty
can be used as a mutex name.
Naturally, I assumed that there is something about the 00000000-0000-0000-0000-000000000000
GUID that Windows OS doesn't like. Maybe it's reserved or something, I thought to myself.
So I, without much further thought, naively arranged things so that a fixed replacement GUID value was going to be used as mutex name instead of Guid.Empty
.
Again, to my surprise, a couple of days later I received report about another crashing bug at the exact same place in code! And the error message from Windows Event Log clearly stated the new replacement value, which proved that my naive conclusion was wrong.
I then devised the following test, expecting a crash that would be observable on my machine, under debugger:
// Random GUID name.
var random = new Mutex(false, Guid.NewGuid().ToString());
random.WaitOne();
random.ReleaseMutex();
random.Dispose();
// Empty GUID name.
var zero = new Mutex(false, Guid.Empty.ToString());
zero.WaitOne();
zero.ReleaseMutex();
zero.Dispose();
// Prefixed GUID name.
var adorned = new Mutex(false, "SomePrefix-" + Guid.NewGuid().ToString());
adorned.WaitOne();
adorned.ReleaseMutex();
adorned.Dispose();
As expected, all three cases worked properly under debugger. I haven't yet had the chance to test these cases on the actual server where my ASP.NET app is crashing, because... well, because procedure. I'll get there in the next day or so.
The question I'm trying to answer in the mean time is: why wouldn't these values possibly work on one specific server? Is it a configuration issue? Rights issue? Something about the GUID substrings? Or is it something else entirely?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
事实证明,服务器上确实有一个名称冲突正在运行我的ASP.NET应用程序。这是该应用程序的另一副本,该应用程序与第一个一起安装,并在将它们部署到实际生产实例之前偶尔用于测试不同的配置。 !感谢@hans ke st伟大的提示!
这就是为什么任何常见共享的GUID值(例如'00000000-0000-0000-0000-0000-00000000000000000000'以及我尝试过的固定替换)可能会导致此问题。这正是观察到的。
首先,我很想引入一个唯一的前缀来修补问题,但最后,我决定遵循 @charlieface的提示,并提出了另一种不涉及静音的同步方法,而是一个同步方法custom
contrentDictionary< string,Smaphoreslim>
存储库。It turned out that there was indeed a name clash on the server that was running my ASP.NET app. It was another copy of the app which was installed alongside the first and used occasionally for testing different configurations before deploying them to the actual production instance. Doh! Thanks @Hans Kesting for the great hint!
That is why basically any commonly shared GUID value as mutex name (such as '00000000-0000-0000-0000-000000000000', as well as the fixed replacement I tried) could cause this problem. Which is exactly what was observed.
At first, I was tempted to introduce an app-unique prefix to patch the issue, but in the end, I decided to follow @Charlieface's hint, and came up with a different method of synchronization that doesn't involve mutexes, but rather a custom
ConcurrentDictionary<string, SemaphoreSlim>
repository.