簡體   English   中英

C#我正確使用鎖嗎?

[英]C# Am i using lock correctly?

我目前正在嘗試編寫一個線程安全的記錄器類。 我對這方面的正確設計和最佳實踐不是很熟悉。 我的代碼有缺陷嗎?

public class WriteStuff
{
    private readonly StreamWriter m_Writer;
    private readonly object m_WriteLock = new object ();

    public WriteStuff(String path)
    {
        m_Writer = File.CreateText (path);

        m_Writer.WriteLine ("x");
        m_Writer.Flush ();
    }

    public void ListenTo(Foo foo)
    {
        foo.SomeEvent += new EventHandler<SomeArgs> (Foo_Update);
    }

    private void Foo_Update(object sender, SomeArgs args)
    {
        lock (m_WriteLock) {
            m_Writer.WriteLine (args);
            m_Writer.Flush ();
        }
    }
}

嗯,這看起來對我好; 我可能IDisposable實現為Close()文件的一種方法,但是......

當然,您也可以使用任何(許多)預先封裝的日志框架。


更新:

一想法:您可能想要考慮如果文件已經存在會發生什么; 你不想踩踏你的日志......

您發布的內容從多線程角度看起來很好。 雖然我可能是錯的,但似乎任何其他代碼執行某些多線程(甚至使用foo對象)應該是安全的。 當然,我在代碼段中看不到任何死鎖

還有一些值得注意的事情(除了非常小心死鎖和嚴格測試以確保它們不會發生):

  • 最好是把一個鎖周圍的代碼在構造函數中,我相信這是可能在某些情況下,該方法可以前的構造塊已經完成執行調用。 (如果我錯了,請有人糾正我。)
  • 在這種情況下, StreamWriter對象是私有的,這很好。 如果它是受保護的或內部的,你肯定必須小心其他代碼如何使用該對象(實際上我認為最好幾乎總是將這些對象聲明為私有)。
  • 你已經完成了正確的鎖定! 鎖定單獨的私有實例對象始終是最安全的,因為您知道該對象不能被您自己的任何其他代碼鎖定(如果您鎖定this對象或StreamWriter對象本身則不是這種情況)。

盡管如此,我可能會遺漏一些東西,並且上面沒有顯示的其他代碼可能會導致問題的可能性很小,但據我所知,除了構造函數代碼可能缺少鎖定之外,代碼沒有缺陷。 當您開始執行更復雜的多線程時,尤其是跨類/實例,您更可能需要注意死鎖情況。

無論如何,希望有所幫助。

事件處理程序與事件生成器位於同一個線程上,這意味着您的應用程序可能最終被日志文件寫入阻止。

private void Foo_Update(object sender, SomeArgs args)        { 
    ThreadPool.QueueUserWorkItem(WriteAsync, args);
}

private void WriteAsync(object state) {  
    SomeArgs args = (SomeArgs)state;    
    lock (m_WriteLock) {                        
       m_Writer.WriteLine (args);                        
       m_Writer.Flush ();                
   }        
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM