c#中这两种锁的区别

本文关键字:区别 两种 | 更新日期: 2023-09-27 18:04:25

在我的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个线程可以并发访问它。我有以下方法:-

  1. 在类级别定义private object 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();
        }
    }
    
  2. 在GenerateWebSiteThumbnailImage函数中定义私有对象locker = new object(),并使用与第1点相同的代码

请帮助我了解这两种方法的区别,这是否有助于我达到预期的结果

c#中这两种锁的区别

这些都不起作用。您需要一个锁对象为static,因此在类的每个实例之间共享

private static object _locker = new Object();

不能在函数中创建静态变量,因此方法#2不能使用。第一种方法只在函数位于单例中的情况下才有效。

如果你想要一个合适的锁,这样它只能在整个机器上被调用一次,你需要一个Mutex

如果在函数内部定义锁对象,则每次进入函数时都会重新创建锁对象,因此根本无法工作——所有线程都将同时进入函数。对于线程安全的代码,需要在类级别声明锁对象。