difference between these two locks in c#
I have the following function inside my WCF service. This function is used to create html page. It creates it using WebBrowser control of windows forms.
public Bitmap Convert(string htmlContent, int faceSheetWidth, int faceSheetHeight)
{
tempFileName = Guid.NewGuid().ToString().Replace("-", "");
tempImageName = Guid.NewGuid().ToString().Replace("-", "");
try
{
width = faceSheetWidth;
height = faceSheetHeight;
SaveHtmlContent(htmlContent);
//Thread m_thread = new Thread(new ThreadStart(GenerateWebSiteThumbnailImage));
Thread m_thread = new Thread(() =>
{
try
{
GenerateWebSiteThumbnailImage();
}
catch (Exception ex)
{
LoggingHelper.LogException(ex, Source.EDiscFacilityService);
LoggingHelper.LogException(new Exception("FaceSheet can not be created."), Source.EDiscFacilityService);
}
});
m_thread.SetApartmentState(ApartmentState.STA);
m_thread.Start();
m_thread.Join();
}
void GenerateWebSiteThumbnailImage()
{
WebBrowser m_WebBrowser = null;
try
{
m_WebBrowser = new WebBrowser();
m_WebBrowser.ScrollBarsEnabled = false;
开发者_StackOverflow m_WebBrowser.Navigate(tempLocation);
m_WebBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(m_WebBrowser_DocumentCompleted);
while (m_WebBrowser.ReadyState != WebBrowserReadyState.Complete)
Application.DoEvents();
}
catch {
}
finally
{
if(m_WebBrowser != null)
m_WebBrowser.Dispose();
}
}
void m_WebBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
WebBrowser m_WebBrowser = null;
try
{
m_WebBrowser = (WebBrowser)sender;
m_WebBrowser.ClientSize = new Size(this.width, this.height);
m_WebBrowser.ScrollBarsEnabled = false;
m_WebBrowser.Width = this.width;
m_WebBrowser.Height = this.height;
m_Bitmap = new Bitmap(m_WebBrowser.Bounds.Width, m_WebBrowser.Bounds.Height);
m_WebBrowser.BringToFront();
m_WebBrowser.DrawToBitmap(m_Bitmap, m_WebBrowser.Bounds);
m_Bitmap = (Bitmap)m_Bitmap.GetThumbnailImage(width, height, null, IntPtr.Zero);
}
catch { }
}
I have to lock calls to GenerateWebSiteThumbnailImage so that no 2 threads can access it concurrently. I have the following ways :-
Define private object locker = new object() at class level and change the method as follows:-
void GenerateWebSiteThumbnailImage() { WebBrowser m_WebBrowser = null; try { lock (locker) { m_WebBrowser = new WebBrowser(); m_WebBrowser.ScrollBarsEnabled = false; m_WebBrowser.Navigate(tempLocation); m_WebBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(m_WebBrowser_DocumentCompleted); while (m_WebBrowser.ReadyState != WebBrowserReadyState.Complete) Application.DoEvents(); } } catch { } finally { if(m_WebBrowser != null) m_WebBrowser.Dispose(); } }
Define private object locker = new object() inside GenerateWebSiteThumbnailImage function and use the same code as in point 1.
Please help me understand the difference in these two approaches and will this help me in achieving desired result.
None of this will work. You need a lock object to be static
, so shared between each instance of the class.
private static object _locker = new Object();
You cannot create a static variable in a function, so approach #2 is out. The first one will work only if the function resides in a singleton.
If you want a proper lock, so that it can only be called once on the whole machine, you want a Mutex
.
If you define the lock object inside the function, it will get recreated every time you go into the function, and therefore won't work at all -- all threads will go into the function simultaneously. You need to declare the lock object at the class level for thread-safe code.
精彩评论