在ASP.Net应用程序中锁定单例公共方法与否

时间:2012-07-06 10:54:19

标签: c# asp.net thread-safety

我有一个ASP.Net应用程序,它引用一个包含单例的DLL。单例只包含两个可公开访问的方法,没有公共属性。 Web应用程序在Application_Start期间创建此单例的实例。然后在整个应用程序生命周期中都可以使用它。

单例保持与第三方应用程序的连接,并侦听在第三方应用程序中触发的许多不同事件。这些事件会在单例中记录和处理,并在它们发生时进行。

当用户访问Web应用程序时,他们的请求在单例上使用公共方法,而单例又使用私有成员数据来调用第三方应用程序上的方法。这些调用都在try ... catch块中。

我是否应该锁定公共方法以保持线程安全,如果是这样,System.Object类型的简单私有成员(仅用于锁定目的)是否足够?

这是单身人士的一些'伪代码'。我希望我的问题可以理解。

using My3rdPartyDLL;

public sealed class MySingleton
{
    private static MySingleton instance = new MySingleton();
    private Object lockObj = new Object();

    private My3rdPartyAPI myAPI = null;


    public static MySingleton Instance
    {
        get{ return instance; }
    }   

    static MySingleton()
    {
    }

    private MySingleton() 
    {
        Initialise(); // Creates third party API and hooks up events.
    }

    // Here is the public method that I want to ensure is
    // thread safe.
    public void SomePublicMethod(String myString)
    {
        lock (lockObj)
        {
            try
            {
                My3rdPartyDLL.MyMethod(myString);
            }
            catch (Exception ex)
            {
                // deal with exception
            }
        }
    }

    private void My3rdParty_Event(EventObj obj)
    {
        MyEventLogger.WriteToLog(obj);  
    }
}

1 个答案:

答案 0 :(得分:1)

  

一个好处,但是第三方是否是线程安全的知识是   不适合我。所以,我创建了单例来维护单个   我的Web App和API之间的凝聚力。我想如果我   不能确定第三方API是线程安全的,我应该是防御性的   在我自己的代码中处理它。也许我刚回答了自己的问题   问题......如果是这种情况,是使用lockObj的好方法   处理这个?

鉴于您无法确定外部方法是否是线程安全的,因此最好同步对它的调用。

您可以锁定静态lockObj,但请注意性能。如果您正在服务大量请求/秒,那么您将遇到问题(等待其他请求释放监视器的请求),如果在每个请求时调用该方法,或者在一次/请求(或更多)时调用接近的速率

由于您正在锁定单个方法,因此您应该使用lock。因此ManualResetEventMonitor和替代方案没有真正的用途。