锁定一个ASP.NET应用程序变量 [英] Locking an ASP.NET application variable

查看:114
本文介绍了锁定一个ASP.NET应用程序变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的ASP.NET应用程序中使用第三方Web服务。呼叫的第三方web服务必须被同步,但ASP.NET是明显的多线程和多个页面请求可以制备导致同时呼叫的第三方web服务。调用Web服务被封装在自定义对象。我的想法是将对象存储在应用程序变量,并使用C#lock关键字来强制同步使用它。

我很紧张,因为我是新来的多线程概念,我读过你不应该锁定一个公共对象(我的应用程序变量是有效)。我也看到,如果code的锁定块失败(这可能如果Web服务失败),那么它可能会破坏应用程序域和关闭应用程序。

我要指出,第三方Web服务在我的网站很少使用,这将是罕见的2请求它是在同一时间进行。

下面是我如何向Web服务调用的粗略code样品:<​​/ P>

  ThirdPartWebService objWebService =应用[ThirdPartWebService作为ThirdPartWebService;
锁定(objWebService)
{
  objWebService.CallThatNeedsToBeSynchronized();
}


解决方案

如果这是至关重要的,你应该只在任何时候,我建议你写你自己的Windows服务,以服务的单一调用。这取决于你有多少容错想要的。

让说,例如您对Web服务的调用,但随后的应用程序池被回收。当一个新的请求进来,将您的应用程序的新实例,那么这可能使调用Web服务(即使其他实例正在运行)来处理。

您可以通过这个开了一个窗口服务,然后使用轮询机制从客户端到检查服务是否已经完成(客户会问IIS是你做的,IIS会看从窗口服务,一些迹象表明,这是完成)。这种做法将避免IIS锁定任何东西,你就不会浪费关键资源,如在线程池中的线程等待一个第三方服务。

您永远不应该在你的web应用程序一个单一的资源锁定...它只是太冒险了。

修改

另一种选择是,直接使用监控对象

 如果(System.Threading.Monitor.TryEnter(syncObj,10))
    {        尝试
        {
            // CallWebService
        }
        最后
        {
            System.Threading.Monitor.Exit(syncObj);
        }
    }
    其他
    {
        //告诉客户,他们仍在等待    }

TryEnter将阻塞,直到锁被制成或10毫秒已经过去了。然后,您可以在您的超时告诉他们需要重试的客户端。然后,您可以让您的客户code决定是否应该重新发出请求。你也可以使用一个信号量或互斥(忘了哪一个更appropiate这里)。但它会假设你有权限使用它们,给你的东西,你可以在机器级这将prevent应用循环利用的情况下锁定。

I'm using a 3rd party web service in my ASP.NET application. Calls to the 3rd party web service have to be synchronized, but ASP.NET is obviously multi-threaded and multiple page requests could be made that result in simultaneous calls to the 3rd party web service. Calls to the web service are encapsulated in a custom object. My thought is to store the object in an application variable and use the C# lock keyword to force synchronized use of it.

I'm nervous, because I'm new to multi threaded concepts and I've read that you shouldn't lock a public object (which my application variable effectively is). I've also read that if the locked block of code fails (which it could if the web service fails), then it could destabilize the app domain and bring down the application.

I should mention that the 3rd party web service is rarely used in my website and it's going to be rare that 2 requests to it are made at the same time.

Here's a rough code sample of how I'd make calls to the web service:

ThirdPartWebService objWebService = Application["ThirdPartWebService"] As ThirdPartWebService;
lock (objWebService)
{
  objWebService.CallThatNeedsToBeSynchronized();
}

解决方案

If it is vital you should only have a single call to the service at any time I recommend you write your own Windows Service. This depends on how much fault tolerance you want.

Let's say for example you make a call to the web service, but then the application pool is recycled. When a new request comes in it would be handled by a new instance of your application which could then make the call to the web service (Even if the other instance is running).

You could pass this off to a windows a service, then use a polling mechanism from the client to check if the service has finished (Client would ask IIS are you done, IIS would look for some indication from windows service that it was done). This approach will avoid locking anything in IIS, and you won't waste critical resources such as threads in your thread pool waiting on a third party service.

You should never lock on a single resource in your web application...it's just too risky.

Edit

Another option is to use the Monitor object directly:

    if (System.Threading.Monitor.TryEnter(syncObj,10))
    {

        try
        {
            //CallWebService
        }
        finally
        {
            System.Threading.Monitor.Exit(syncObj);
        }
    }
    else
    {
        //Tell Client they are still waiting

    }

TryEnter will block until a lock is made or 10 milliseconds has passed. You could then in your timeout tell the client they need to retry. You could then have your client code decide if it should reissue the request. You could also use a semaphore or mutex (forget which one is more appropiate here). But it would assuming you have permissions to use them, give you something you can lock on at the machine level which would prevent the app recycling use case.

这篇关于锁定一个ASP.NET应用程序变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆