我正在使用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引用) –