我有一个 Web 服务方法,在其中创建特定类型的对象,使用它几秒钟,然后处理它。由于多个线程同时创建和使用此类的实例会出现问题,因此我需要限制该方法,以便一次只有一个调用者拥有这些对象之一。
为此,我创建一个私有(private)静态对象:
private static object _lock = new object();
...然后在 Web 服务方法中我围绕关键代码执行此操作:
lock (_lock)
{
using (DangerousObject dob = new DangerousObject())
{
dob.MakeABigMess();
dob.CleanItUp();
}
}
不过,我不确定这是否有效。我有这个权利吗?此代码能否确保一次仅实例化并使用一个 DangerousObject
实例?或者每个调用者都会获得自己的 _lock
副本,从而使我的代码变得可笑?
更新:来自 Ben Voigt 答案中的链接,我想我需要这样做:
Mutex m = new Mutex(false, @"Global\MyMutex");
m.WaitOne();
try
{
using (DangerousObject dob = new DangerousObject())
{
dob.MakeABigMess();
dob.CleanItUp();
}
}
catch (Exception ex)
{
// what could possibly go wrong?
}
finally
{
m.ReleaseMutex();
}
这应该与我的 lock
代码几乎相同,但它将使用全局对象(因为互斥体名称中的“Global\”前缀)。我希望如此。
最佳答案
当然,这取决于你的对象造成的困惑的范围。
每个 AppDomain 中只有一个 _lock 实例。如果您的对象期望独占访问 AppDomain 之间共享的资源(例如特定文件),这可能会很麻烦。应在什么级别允许共享访问?通过不同的过程?由不同的用户?绝不?这将帮助我们找到解决方案。
编辑:如果您使用静态成员变量来锁定计算机全局资源,请害怕,非常害怕。
也适用于 IIS 7
http://technet.microsoft.com/en-us/library/cc735056(WS.10).aspx
编辑:对于实际的机器范围的锁,请查看 System.Threading.Mutex使用 LOCAL\或 GLOBAL\前缀,具体取决于您是否想要每个用户 session 或计算机范围内有一个互斥锁。
编辑:使用 try/finally 来确保互斥锁被释放。
关于c# - 如何在 ASMX Web 服务中一次限制一个调用者对特定类的访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2634260/