Dot-Net
將 IDisposable 作為參數傳遞
將 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 實例可能是一個好主意,這樣您就不必過多地考慮所有者。