Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reuse a Process instance with slightly different ProcessStartInfo instances?

I have the following code that starts robocopy as a Process. I also need to do database queries to determine which directories I need to copy each time robocopy is called so I used ProcessStartInfo to control the arguments passed.

internal class Program
{
    private static void Main(string[] args)
    {
        using (var context = new MyDbContext())
        {
            IEnumerable<ProcessStartInfo> 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<ProcessStartInfo> 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)));
    }
}

How can I reuse Process instances returned by the static Process.Start(ProcessStartInfo) inside the foreach loop and how can I Dispose of them properly?

like image 236
rexcfnghk Avatar asked Dec 06 '22 21:12

rexcfnghk


1 Answers

You cannot re-use a Process object. The Process class behaves like all of the other .NET classes that wrap an operating system object. Like Socket, Bitmap, Mutex, FileStream, etcetera. They are tiny little cookies that are very cheap to bake and take very little space on the GC heap. They track the lifetime of the underlying OS object carefully, once the object is dead, the .NET wrapper object is no longer useful either.

The Process class signals that the cookie was eaten with its Exited event and HasExited property. It has some post-bite properties that are useful, ExitCode and ExitTime.

But that's where it ends, if you want to create another process then you have to bake another cookie. Simple to do with the new keyword or the Start() factory function. Don't try to optimize it, there's no point and it can't work. Re-using ProcessStartInfo is fine, it is not a wrapper class.

like image 153
Hans Passant Avatar answered Feb 02 '23 01:02

Hans Passant