簡體   English   中英

我的代碼存在任何並發問題

[英]Any Concurrency Issues with my code

我試圖創建一個線程安全的方法。

有人在以下代碼中看到任何並發問題嗎?

在我看來,這很好, 盡管我永遠無法找到一種方法來測試這種方法的並發性。 任何幫助,將不勝感激。

   //static locker for thread synchronization
   private static readonly System.Object _object3 = new System.Object();

   //this method needs to be thread-safe
   public static void LogToTextFile(string logMessage, LogLevel logType)
    {
       //make sure only one thread executes this file writing code at a time            
       lock (_object3)
        {
            using (StreamWriter w = File.AppendText(@"c:\logs\log1.txt");
            {
                w.WriteLine("\r\n{0} logged at {1} {2} : {3}", logType.ToString().ToUpper(), DateTime.Now.ToLongTimeString(), DateTime.Now.ToLongDateString(), logMessage);
            }
        }
    }

這段代碼沒有並發問題,因為由於lock語句,您只允許一個線程寫入文件。

考慮到您lock范圍適當的對象,因此我發現您的代碼沒有並發問題。

但是,正如注釋中提到的millimoose一樣,您存在潛在的性能問題。 如果兩個線程嘗試同時LogToTextFile ,則一個線程將首先獲取鎖,另一個線程將在打開,寫入和關閉文件時阻塞。 這可能是不可接受的,具體取決於您的線程在做什么。

如果我提到的是一個問題,則必須實現更復雜的線程安全記錄器。 通常,將有一個隊列,日志事件會快速寫入該隊列。 然后有另一個線程定期喚醒,並將隊列清空到磁盤上的文件。 隊列上的所有操作都帶有鎖。

另一個可能更好的解決方案是保持文件打開狀態,並使用同步的TextWriter進行寫入。 TextWriter.Synchronized提供了圍繞TextWriter的線程安全包裝器:

對返回的包裝器的所有寫操作都是線程安全的。 您調用此方法以確保一次僅一個線程可以在返回的TextWriter實例上執行這些方法。

這是一個簡單的實現。 注意,這尚未經過測試。

public static class MyLogger
{
    private static TextWriter s_writer;

    // Not thread-safe. Call this before other threads are allowed to call Log.
    public void Open(string filename) {
        s_writer = TextWriter.Synchronized( File.AppendText(filename) );
    }

    // Also not thread-safe.
    public void Close() {
       s_writer.Dispose();
    }

    // Thread-safe.
    public void Log(string logMessage, LogLevel logType) {
        s_writer.WriteLine("\r\n{0} logged at {1} {2} : {3}",
            logType.ToString().ToUpper(), DateTime.Now.ToLongTimeString(),
            DateTime.Now.ToLongDateString(), logMessage);
    }    
}

此特定功能內沒有並發問題。 lock語句將適當地緩和對內部代碼的訪問。

但是,訪問@"c:\\logs\\log1.txt"仍然存在潛在的並發問題。 應用程序的另一部分或同一台計算機上的另一個進程可能會嘗試與代碼同時寫入文件。 因此,即使使用此鎖定, StreamWriter代碼也可能會失敗。

沒有辦法解決這種類型的並發問題。 文件系統是一個共享資源,您沒有真正的能力來保護。 取而代之的是,您的代碼需要接受文件系統訪問可能失敗並正確處理該后果的消息。

通常,在處理日志記錄功能時,我會使用try / catch包裝文件系統訪問權限,並吞下發生的所有異常。 否則,您將冒着日志記錄功能失敗的風險關閉應用程序。 對於您的方案,這可能會接受,也可能無法接受。

暫無
暫無

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

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