如何在 ASMX Web 服务中一次限制一个调用者对特定类的访问?

发布于 2024-08-28 23:35:42 字数 977 浏览 1 评论 0原文

我有一个 Web 服务方法,在其中创建特定类型的对象,使用它几秒钟,然后处理它。由于多个线程同时创建和使用此类的实例所引起的问题,我需要限制该方法,以便一次只有一个调用者拥有这些对象之一。

为此,我创建一个私有静态对象:

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\”前缀)。我希望。

I have a web service method in which I create a particular type of object, use it for a few seconds, and then dispose it. Because of problems arising from multiple threads creating and using instances of this class at the same time, I need to restrict the method so that only one caller at a time ever has one of these objects.

To do this, I am creating a private static object:

private static object _lock = new object();

... and then inside the web service method I do this around the critical code:

lock (_lock)
{
    using (DangerousObject dob = new DangerousObject())
    {
        dob.MakeABigMess();
        dob.CleanItUp();
    }
}

I'm not sure this is working, though. Do I have this right? Will this code ensure that only one instance of DangerousObject is instantiated and in use at a time? Or does each caller get their own copy of _lock, rendering my code here laughable?

Update: from a link in Ben Voigt's answer, I think I need to do this instead:

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();
}

This should function pretty much the same as my lock code, but it will instead use a global object (because of the "Global\" prefix in the mutex' name). I hope.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

南渊 2024-09-04 23:35:42

当然,这取决于你的对象造成的混乱的范围。

每个 AppDomain 中只有一个 _lock 实例。如果您的对象期望独占访问 AppDomain 之间共享的资源(例如特定文件),这可能会很麻烦。应在什么级别允许共享访问?通过不同的过程?由不同的用户?绝不?这将帮助我们为您找到解决方案。

编辑:如果您使用静态成员变量来锁定计算机全局资源,请害怕,非常害怕。

http: //www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/0e570911-b88e-46be-96eb-a82f737dde5a.mspx?mfr=true

也适用于 IIS 7

http://technet.microsoft.com/en-us/library/cc735056(WS. 10).aspx

编辑:对于实际的计算机范围的锁定,请查看 System.Threading.Mutex 使用 LOCAL\ 或 GLOBAL\ 前缀,具体取决于您是否想要每个用户会话或计算机范围内有一个互斥体。

编辑:使用 try/finally 来确保互斥体被释放。

It depends on the scope of the mess your object makes, of course.

There will be only one instance of _lock in each AppDomain. If your object expects exclusive access to a resource shared between AppDomains, such as a particular file, this might be trouble. At what level should shared access be allowed? By different processes? By different users? Never? That will help us find you a solution.

EDIT: Be afraid, be very afraid, if you're using static member variables to lock machine-global resources.

http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/0e570911-b88e-46be-96eb-a82f737dde5a.mspx?mfr=true

Applies to IIS 7 as well

http://technet.microsoft.com/en-us/library/cc735056(WS.10).aspx

EDIT: For an actual machine-wide lock, have a look at System.Threading.Mutex Use either the LOCAL\ or GLOBAL\ prefix depending on whether you want one mutex per user session or computer-wide.

EDIT: Use a try/finally to make sure the Mutex gets released.

可是我不能没有你 2024-09-04 23:35:42

您可能会遇到这样的问题:同时发出许多请求,并且客户端请求开始超时,因为它们都在等待锁定。您还可能会在 Webfarm 场景中遇到问题,其中多个服务器正在处理请求,因此每个服务器都有自己的 _lock。我建议使用队列代替。如果每个客户端进来并向某个队列添加一条消息,则单独的服务可以一次处理一个队列中的消息,并且客户端无需等待。

You could run into problems where many requests are made at once and client requests start timing out as they are all waiting on the lock. You could also run into issues in a webfarm scenario where multiple servers are handling the requests and so each has its own _lock. I would suggest using a queue instead. If each client comes in and adds a message to some queue, then a separate service can process the messages from the queue, one at a time, and the clients will not have to wait.

眼眸里的那抹悲凉 2024-09-04 23:35:42

我建议使用单例模式或工厂模式。

I would suggest either using a Singleton or a Factory pattern.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文