我有一个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);
}
}
答案 0 :(得分:1)
一个好处,但是第三方是否是线程安全的知识是 不适合我。所以,我创建了单例来维护单个 我的Web App和API之间的凝聚力。我想如果我 不能确定第三方API是线程安全的,我应该是防御性的 在我自己的代码中处理它。也许我刚回答了自己的问题 问题......如果是这种情况,是使用lockObj的好方法 处理这个?
鉴于您无法确定外部方法是否是线程安全的,因此最好同步对它的调用。
您可以锁定静态lockObj
,但请注意性能。如果您正在服务大量请求/秒,那么您将遇到问题(等待其他请求释放监视器的请求),如果在每个请求时调用该方法,或者在一次/请求(或更多)时调用接近的速率
由于您正在锁定单个方法,因此您应该使用lock
。因此ManualResetEvent
,Monitor
和替代方案没有真正的用途。