簡體   English   中英

用靜態方法管理一次性物品

[英]Managing disposable objects within static methods

public class SimpleLogger
{
    static readonly string logFile = ConfigurationManager.AppSettings["LogFile"];

    static StreamWriter GetStream()
    {
        return File.Exists(logFile) ?
            File.AppendText(logFile) : File.CreateText(logFile);
    }

    public static void Write(string msg)
    {
        using (var sw = GetStream())
        {
            sw.Write(msg);
        }
    }
}

上面的代碼無法使用,因為它似乎無法正確關閉/處理流。 隨后的寫操作將給出“正在使用的文件” IOException。

如果將類修改為使用非靜態方法,則它似乎可以正常工作。

我不明白為什么會有任何行為上的差異?

處置很好; GetStream提供了一個開放的GetStream器; Write關閉/處理它-排序。 如果我猜的話,不過,問題是同時使用-即多線程(特別是在Web應用程序)訪問該文件在同一時間 如果是這樣,可以選擇以下選項:

  • Write (以及任何其他訪問文件)同步,因此只有一個調用者可以嘗試可能有一次打開該文件
  • 使用已經可以解決此問題的預先屏蔽的日志記錄框架(常見的方法包括同步,但也包括:在本地緩沖數據,然后定期向下推送數據-避免一遍又一遍地打開文件)

特別是; 您唯一的靜態狀態是文件路徑本身。 因此,將其用作靜態方法與實例方法之間沒有顯着差異。

附帶說明一下, File.AppendAllText在這里可能有用,但不能避免並發問題。

我認為從靜態更改為實例不會解決問題,因為它們最終都爭用靜態資源(文件)。 這個答案可能會幫助您。 也許如果您將兩個方法都保留為靜態並聲明一個靜態同步對象以調用線程進行鎖定(因為資源本身是靜態的)會有所幫助?例如:

private static object _objectLock = new object();

用於同步從多個線程對文件的訪問,因此:

public static void Write(string msg)      
{        
    lock(_objectLock)
    {  
        using (var sw = GetStream())          
        {              
            sw.Write(msg);          
        }
    }      
}  

暫無
暫無

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

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