c# - System.Diagnostics.Process 实例可以被垃圾收集吗?

标签 c# mono

我正在使用 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 可以被垃圾回收,回调函数 complete 永远不会被调用。

但我真的不想将 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。

最佳答案

应用程序中任何没 Root过的对象都是垃圾收集的候选对象。为了确保你的回调触发,你需要找到一些地方来存储对 proc 的引用,否则你将有未定义的行为。

在您的情况下,一个选择是返回一个封装 proc 的对象,而不通过公共(public)接口(interface)公开它。不幸的是,在您的情况下,您必须将一些底层实现泄漏给 ConvertWavToMp3 的调用者,以确保发生所需的行为。

关于c# - System.Diagnostics.Process 实例可以被垃圾收集吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6769494/

相关文章:

c# - 提取链接正则表达式 c#

c# - 基于其他列合并 C# 列表中一列的多行

c# - DBreeze 在单声道中无法正常运行

javascript - 在 Javascript 中将立体声音频转换为单声道

android - 单色机器人 : Unsigned Binary upload to Amazon

cocoa - 以编程方式打开 Mac 帮助菜单

c# - 如何将用户名/密码凭据从 php 客户端传递到自托管 wcf 服务?

c# - WebClient 请求返回空字符串

c# - 一种不失色的边缘检测算法

.net - 让 Mono 与 Centos 5.6 一起工作