2015-05-18 2 views
3

У меня есть следующий код, начинающийся robocopy как Process. Мне также нужно делать запросы базы данных, чтобы определить, какие каталоги мне нужно копировать каждый раз, когда robocopy вызывается так, что я использовал ProcessStartInfo для управления переданными аргументами.Как повторно использовать экземпляр процесса с несколькими разными экземплярами ProcessStartInfo?

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))); 
    } 
} 

Как можно повторно использовать Process экземпляры, возвращенные staticProcess.Start(ProcessStartInfo) внутри цикла foreach и как я могу Dispose их правильно?

+1

Что именно вы подразумеваете под «повторным использованием» экземпляров «Процесс»? Вы можете распоряжаться ими должным образом, вызывая 'Dispose' (или используя' using') ... – vesan

+0

@vesan. По моему мнению, 'Process.Start (ProcessStartInfo)' запускает новый 'Процесс' каждый раз, когда он вызывается, я хотите, чтобы только один процесс robocopy был запущен с различными переданными в него аргументами, возможно ли это? – rexcfnghk

+0

Если «robocopy» (я не очень хорошо разбираюсь в нем) сам поддерживает несколько переданных наборов аргументов, тогда вам нужно начать новый процесс для каждой итерации. – vesan

ответ

7

Вы не можете повторно использовать объект Process. Класс Process ведет себя как все другие классы .NET, которые обертывают объект операционной системы. Как Socket, Bitmap, Mutex, FileStream и т. Д. Это крошечные кусочки, которые очень дешевы для выпечки и занимают очень мало места на куче GC. Они тщательно отслеживают время жизни базового объекта ОС, после того как объект мертв, объект оболочки .NET тоже не полезен.

Класс Process сообщает, что cookie был съеден с его событием Exited и HasExited. Он имеет некоторые свойства после укуса, которые полезны, ExitCode и ExitTime.

Но это конец, если вы хотите создать другой процесс, тогда вы должны испечь еще один файл cookie. Простота использования ключевого слова или функции фабрики Start(). Не пытайтесь его оптимизировать, нет смысла, и он не может работать. Повторное использование ProcessStartInfo в порядке, это не класс оболочки.

+0

Хороший ответ с пояснениями о внутренних функциях 'Process'. Благодарю. – rexcfnghk

1

Вам не нужно повторно использовать класс Process - это всего лишь оболочка для основного процесса. И когда процессы заканчиваются, они ушли, полностью - это основной момент, когда процесс в первую очередь.

Вместо этого, кажется, что вы действительно хотите, чтобы просто убедиться, что только один из этих robocopy процессов проходит в то время, которое довольно легко:

using (var context = new MyDbContext()) 
{ 
    IEnumerable<ProcessStartInfo> 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. 
    } 
} 
Смежные вопросы