如何重用具有略微不同的ProcessStartInfo实例的Process实例?

我有以下代码启动robocopy作为Process 。 我还需要进行数据库查询以确定每次调用robocopy我需要复制哪些目录,因此我使用ProcessStartInfo来控制传递的参数。

 internal class Program { private static void Main(string[] args) { using (var context = new MyDbContext()) { IEnumerable processInfos = GetProcessInfos(context, args[0]); foreach (ProcessStartInfo processInfo in processInfos) { // How can I reuse robocopy Process instances and // how can I dispose of them properly? Process.Start(processInfo); } } } private static IEnumerable GetProcessInfos(MyDbContext context, string directory) { const string defaultRobocopyFormatString = "{0} {1} /mir /tee /fft /r:3 /w:10 /xd *Temp*"; var directoryInfo = new DirectoryInfo(directory); return from dir in directoryInfo.GetDirectories() from myEntity in context.MyEntities where dir.Name == myEntity.Name select new ProcessStartInfo("robocopy", string.Format(defaultRobocopyFormatString, Path.Combine("C:\Test", dir.Name), Path.Combine("C:\Test_bak", dir.Name))); } } 

如何在foreach循环中重用static Process.Start(ProcessStartInfo)返回的Process实例,如何正确Dispose它们?

您无法重复使用Process对象。 Process类的行为与包装操作系统对象的所有其他.NET类一样。 像Socket,Bitmap,Mutex,FileStream等。 它们是很小的小cookies,它们非常便宜,可以在GC堆上占用很少的空间。 它们仔细跟踪底层OS对象的生命周期,一旦对象死了,.NET包装器对象也不再有用。

Process类通过其Exited事件和HasExited属性发出cookie信号。 它有一些有用的后咬合属性,ExitCode和ExitTime。

但这就是它结束的地方,如果你想创建另一个进程,那么你必须烘焙另一个cookie。 使用new关键字或Start()工厂函数很简单。 不要试图优化它,没有意义,它不能工作。 重用ProcessStartInfo很好,它不是包装类。

您实际上并不需要重用Process类 – 这只是底层流程的包装器。 当流程结束时,它们就完全消失了 – 这是首先制定流程的要点。

相反,您似乎真的只想确保一次只运行其中一个robocopy进程,这非常简单:

 using (var context = new MyDbContext()) { IEnumerable processInfos = GetProcessInfos(context, args[0]); foreach (ProcessStartInfo processInfo in processInfos) { using (var process = Process.Start(processInfo)) { // Blocks until the process ends process.WaitForExit(); } // When the `using` block is left, `process.Dispose()` is called. } }