3

我有一个引用包含单例的 DLL 的 ASP.Net 应用程序。单例只包含两个可公开访问的方法,没有公共属性。Web App 在 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);  
    }
}
4

1 回答 1

1

好一点,但我不知道第 3 方是否是线程安全的。因此,我创建了单例来维护我的 Web 应用程序和 API 之间的单点内聚。我想如果我不能确定 3rd Party API 是线程安全的,我应该采取防御措施并在我自己的代码中处理它。也许我刚刚回答了我自己的问题......如果是这种情况,使用 lockObj 是一种处理这个问题的好方法吗?

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

您可以锁定一个 static lockObj,但要注意性能。如果您每秒处理大量请求,那么您将遇到问题(请求等待其他请求释放监视器),如果该方法在每个请求或接近一次/请求(或更多)时调用.

由于您要锁定单个方法,因此您应该可以使用lock. ManualResetEvent所以这里对于,Monitor和替代品没有真正的用途。

于 2012-07-06T11:58:34.667 回答