using(p = Process.Start(command))
यह संकलन के रूप में Process
वर्ग IDisposable
लागू करता है, फिर भी आप वास्तव में Close
विधि कॉल करना चाहते हैं।
तर्क यह होगा कि Dispose
विधि आपके लिए Close
पर कॉल करेगी, और परावर्तक का उपयोग करके सीएलआर में खुदाई करके, हम देख सकते हैं कि यह वास्तव में हमारे लिए ऐसा करता है। अब तक सब ठीक है।
फिर परावर्तक का उपयोग करके, मैंने देखा कि Close
विधि क्या करती है - यह अंतर्निहित देशी Win32 प्रक्रिया संभालती है, और कुछ सदस्य चर को साफ़ करती है। यह (बाहरी संसाधनों को जारी करना) बिल्कुल आईडीस्पोज़ेबल पैटर्न क्या करना चाहिए।
हालांकि मुझे यकीन नहीं है कि यह वही है जो आप यहां प्राप्त करना चाहते हैं।
अंतर्निहित हैंडल को जारी करना बस विंडोज़ को कहता है 'अब मुझे इस अन्य प्रक्रिया को ट्रैक करने में दिलचस्पी नहीं है'। किसी भी समय यह वास्तव में अन्य प्रक्रिया को छोड़ने का कारण नहीं बनता है, या आपकी प्रक्रिया का इंतजार कर सकता है।
यदि आप उन्हें छोड़ना चाहते हैं, तो आपको प्रक्रियाओं पर p.Kill()
विधि का उपयोग करने की आवश्यकता होगी - हालांकि सलाह दी जानी चाहिए कि प्रक्रियाओं को मारना कभी भी अच्छा विचार नहीं है क्योंकि वे स्वयं के बाद साफ नहीं हो सकते हैं, और छोड़ सकते हैं भ्रष्ट फाइलों के पीछे, और इसी तरह।
यदि आप उनके लिए बाहर निकलने के लिए प्रतीक्षा करना चाहते हैं, तो आप p.WaitForExit()
का उपयोग कर सकते हैं - हालांकि यह केवल तभी काम करेगा यदि आप एक समय में एक प्रक्रिया की प्रतीक्षा कर रहे हैं। यदि आप सभी के साथ एक साथ इंतजार करना चाहते हैं, तो यह मुश्किल हो जाता है।
आम तौर पर आप इस के लिए WaitHandle.WaitAll
का उपयोग करते हैं, लेकिन वहाँ के रूप में एक System.Diagnostics.Process
के बाहर एक WaitHandle
वस्तु प्राप्त करने के लिए कोई रास्ता नहीं है, तो आप ऐसा नहीं कर सकते यह (गंभीरता से, WTF माइक्रोसॉफ्ट सोच रहे थे?)।
आप प्रत्येक प्रक्रिया के लिए एक थ्रेड स्पिन कर सकते हैं, और उन धागे में 'WaitForExit' को कॉल कर सकते हैं, लेकिन यह भी करने का गलत तरीका है।
आपको मूल Win32 WaitForMultipleObjects
फ़ंक्शन तक पहुंचने के लिए पी/इनवॉक का उपयोग करना होगा।
यहां एक नमूना है (जो मैं परीक्षण किया है, और वास्तव में काम करता है)
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
static extern uint WaitForMultipleObjects(uint nCount, IntPtr[] lpHandles, bool bWaitAll, uint dwMilliseconds);
static void Main(string[] args)
{
var procs = new Process[] {
Process.Start(@"C:\Program Files\ruby\bin\ruby.exe", "-e 'sleep 2'"),
Process.Start(@"C:\Program Files\ruby\bin\ruby.exe", "-e 'sleep 3'"),
Process.Start(@"C:\Program Files\ruby\bin\ruby.exe", "-e 'sleep 4'") };
// all started asynchronously in the background
var handles = procs.Select(p => p.Handle).ToArray();
WaitForMultipleObjects((uint)handles.Length, handles, true, uint.MaxValue); // uint.maxvalue waits forever
}