I have an ASP.Net application that references a DLL which contains a singleton. The singleton contains only two publically accessible methods and no public properties. The Web App creates an instance of this singleton during Application_Start. This is then available throughout the application lifespan.
The singleton maintains a connection to a 3rd party application, and listens for a number of different events that fire in the third party application. These events are logged and processed within the singleton, as and when they occur.
As users access the web app, their requests make use of a public method on the singleton that, in turn, uses private member data to call a method on the third party application. These calls are within a try…catch block.
Should I lock the public method to maintain thread safety, and if so would a simple private member of type System.Object, that is used only for the purpose of locking, be sufficient?
Here is some ‘pseudo code’ for the singleton. I hope I have made my question understandable.
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);
}
}
Given the fact that you cannot be sure if the external method is thread safe, it is better to synchronize calls to it.
You can lock on a static
lockObj, but watch out for performance. If you are serving a large number of requests/sec then you’ll run into problems (requests waiting for other requests to release the monitor), if the method is called at every requests or a close rate to once/request (or more).Since you’re locking a single method, you should be fine with
lock. So no real use here forManualResetEvent,Monitorand alternatives.