Dot-Net

將 IDisposable 作為參數傳遞

  • October 26, 2013

將 IDisposable 作為參數傳遞給方法並將其放置在該方法中是否是一種好習慣。當您必須使用多個執行緒時,這是不可避免的。好吧,最佳實踐說所有者(呼叫者)應該處理它。

例如

public void MyMethod(MyClass reader){
   using(reader){
       //some code
   }
}

如果所有者(創建執行緒)不再存在怎麼辦?例如

interface IReader : IDisposable {
   string Read();
}

public class MyReader : IReader {

   public string Read()
   {
       return "hellow world";
   }
   public void Dispose()
   {
       //dispose code
   }
}

在這裡你會發現問題…

public void Start() {
   MyReader[] readerSet = new MyReader[5];
   for (int i = 0; i < readerSet.Length; i++) {
       readerSet[i] = new MyReader();
   }
   foreach (IReader reader in readerSet) {
       ThreadPool.QueueUserWorkItem(new WaitCallback(Run), reader);
   }
   //exit after creating threads
}


public void Run(Object objReader) {
   IReader reader = (IReader)objReader;
   using (reader) { 
   //use the reader
   }
}

我認為您最好採用創建委託來保證對象的處置。

例子

public void Start() {
   var makeReader = new Func<IReader>(() => new MyReader()); 
   for (int i = 0; i < 5; i++) {
       ThreadPool.QueueUserWorkItem(Run, makeReader);
   }
}    

public void Run(Object state) {
   var makeReader = (Func<IReader>)state;
   using (var reader = makeReader()) { 
       //use the reader
   }
}

不,主人應該處置它。所有者通常是首先創建 IDisposable 實例的對象。您可以在此處閱讀有關 IDisposable 最佳實踐的資訊。

請通過 Dispose 方法傳遞地處理您的類型中定義的任何一次性欄位。您應該在對象控制其生命週期的任何欄位上呼叫 Dispose()。例如,考慮您的對象擁有私有 TextReader 欄位的情況。在您的類型的 Dispose 中,您應該呼叫 TextReader 對象的 Dispose,這將依次釋放其一次性欄位(例如 Stream 和 Encoding),等等。如果在 Dispose(bool disposing) 方法中實現,則只有在 disposing 參數為 true 時才會發生這種情況——在最終確定期間不允許接觸其他託管對象。**此外,如果您的對像不擁有給定的一次性對象,則不應嘗試處置它,因為其他程式碼仍可能依賴它處於活動狀態。**這兩種情況都可能導致難以察覺的錯誤。

盡量減少傳遞的 IDisposable 實例可能是一個好主意,這樣您就不必過多地考慮所有者。

引用自:https://stackoverflow.com/questions/7289910