我的WCF服务中有以下功能。此函数用于创建html页面。它使用Windows窗体的WebBrowser控件创建它。
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;
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 { }
}
我必须锁定对GenerateWebSiteThumbnailImage的调用,以便没有2个线程可以同时访问它。我有以下几种方式: -
在类级别定义私有对象locker = new object()并按如下方式更改方法: -
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();
}
}
在GenerateWebSiteThumbnailImage函数中定义私有对象locker = new object(),并使用与第1点相同的代码。
请帮助我理解这两种方法的不同之处,这将有助于我达到预期的效果。
答案 0 :(得分:1)
如果在函数内部定义了锁定对象,那么每次进入函数时都会重新创建它,因此根本不会工作 - 所有线程都会同时进入函数。您需要在类级别声明锁定对象以获取线程安全的代码。
答案 1 :(得分:1)
这些都不会起作用。您需要一个锁定对象为static
,因此在每个类实例之间共享。
private static object _locker = new Object();
您无法在函数中创建静态变量,因此方法#2已经完成。第一个仅在函数驻留在单例中时才有效。
如果你想要一个正确的锁,以便它只能在整个机器上调用一次,你需要一个Mutex
。