私は、System.Diagnostics.Processクラスを使用して、分離されたプロセスでwavファイルをmp3ファイルに変換しています。このような仕事をしていません方法: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は唯一のローカル変数であるような方法を返すとき、理論的にはそれはもう存在していないので、私はGC心配です。したがって、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参照が必要なくなった場合を除きます) –