【发布时间】:2011-07-20 22:51:28
【问题描述】:
我正在使用 System.Diagnostics.Process 类在单独的进程中将 wav 文件转换为 mp3 文件。完成这项工作的方法是这样的:
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();
}
我很担心 GC,因为 proc 只是一个局部变量,理论上当方法返回时它不再存在。因此,proc可以被垃圾回收,并且永远不会调用回调函数完成。
但我真的不想在某个地方记录 proc 并在进程退出后处理它,因为这会暴露 wav 到 mp3 转换的内部机制。
我对 GC 的担忧是否有效?如果 GC of 是潜在问题,有什么方法可以防止它,而不必在此方法中返回 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。
【问题讨论】: