我正在使用System.Diagnostics.Process類將wav文件轉換爲分離過程中的mp3文件。 ,做這樣的工作方法:我很擔心GC是否可以對System.Diagnostics.Process實例進行垃圾收集?
public void ConvertWavToMp3 (TempFile srcFile, string title, Action<TempFile, Exception> complete)
{
var argument_fmt = "-S --resample 16 --tt {0} --add-id3v2 {1} {2}";
var dstFile = new TempFile(Path.GetTempFileName());
var proc = new System.Diagnostics.Process();
proc.EnableRaisingEvents = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.FileName = "lame";
proc.StartInfo.Arguments = String.Format (argument_fmt,
title,
srcFile.Path,
dstFile.Path);
proc.Exited += delegate(object sender, EventArgs e) {
proc.WaitForExit();
srcFile.Delete();
complete(dstFile, null);
};
proc.Start();
}
因爲PROC只是一個局部變量,理論上不存在了該方法返回時。因此,proc可以被垃圾收集,回調函數完成將永遠不會被調用。
但我並不是真的想記錄某處的proc,並在該進程退出後進行處理,因爲這會暴露如何實現wav到mp3轉換的內部機制。
我對GC的擔心有效嗎?如果GC是潛在的問題,有沒有什麼辦法可以阻止它,而不必用這種方法返回proc?
順便說一句,我在linux上使用Mono。
編輯
感謝的答覆。我確認我需要保留一個過程的副本。因此,這裏是我所做的:
public class LameConverter : IAudioConverter
{
// We need to store a reference to the process in case it was GCed.
IList<Process> _ProcList = new List<Process>();
public void ConvertWavToMp3 (TempFile srcFile, string title, Action<TempFile, Exception> complete)
{
// .. skipped ..
proc.Exited += delegate(object sender, EventArgs e) {
lock (this) {
_ProcList.Remove(proc);
}
proc.Dispose();
srcFile.Delete();
complete(dstFile, null);
};
proc.Start();
lock (this) {
_ProcList.Add(proc);
}
}
}
只要調用者持有至LameConverter參考,我不需要擔心GC了。
非常好的觀察,雖然有一件事情發生,因爲Proc使用內部資源,被其他內部代碼引用它可能不會被GCed,但你說他應該保持該引用某處,以免進程退出和處理程序花費太長時間(除非不再需要proc引用) –