2011-11-07 11 views
5

मुझे लगता है कि एक ही कार्यक्रम के कई सांत्वना अनुप्रयोगों बनाता है एक खिड़कियों रूप है के एक समूह के भीतर से एक सांत्वना आवेदन की हत्या का उपयोग करसफाई सांत्वना अनुप्रयोगों

process.start(). 

मैं कर रहा हूँ (यह कितनी भी बार program.exe कॉल) एप्लिकेशन के विशिष्ट चलने की पहचान करने और इसे साफ तरीके से मारने का एक तरीका ढूंढना (यानी प्रोग्राम.एक्सई की 5 वीं प्रक्रिया को साफ़ रूप से बंद करें लेकिन अन्य सभी प्रक्रियाओं को चलाना छोड़ दें)। मैं आईडी है कि जब प्रक्रियाओं शुरू किए गए दिए गए थे के माध्यम से program.exe से प्रत्येक अलग प्रक्रिया की पहचान करने में सक्षम हूँ, लेकिन मैं किसी भी तरह से आवेदन

process.kill() 

बुला के अलावा अन्य बंद करने के लिए जो एक साफ पास प्रदर्शन नहीं करता असमर्थ हूँ आवेदन के

मुझे विश्वास है कि मैं

उपयोग नहीं कर सकते, क्योंकि आवेदन (यह एक सांत्वना है कि पृष्ठभूमि में चलता है के माध्यम से चलाया जाता है) का उपयोग नहीं है। मैं चल रहा प्रक्रियाओं की सूची से मारने की प्रक्रिया का चयन करने के बाद अपने जीयूआई में एक बटन पर क्लिक करके प्रक्रियाओं को मारने के लिए देख रहा हूं।

मुझे इसकी आवश्यकता क्यों है क्योंकि मुझे बंद होने से पहले प्रत्येक प्रक्रिया के सभी धागे और उत्कृष्ट पहलुओं को बंद करने की आवश्यकता है।

मैं हर नए प्रक्रिया को परिभाषित इस प्रकार,

Process process = new Process(); 
process.StartInfo = info; 

ExecutionDetails details = new ExecutionDetails(run_id, process, info, session_type, strategy_type, name, ExecutionViewModel); 

lock (_runs) 
_runs.Add(run_id, details); // will throw on Add if duplicate id, prevent duplicate 
ExecutionViewModel.NewRun(details); // add to the view model 

process.Start(); 

कहाँ run_id एक GUID कि प्रत्येक प्रक्रिया की पहचान करता है।

एक अलग वर्ग में मेरे पास कोड है जो प्रक्रिया के माध्यम से निष्पादित किया जाता है जिसे केवल कमांड प्रॉम्प्ट के माध्यम से संदर्भित किया जाता है जो प्रोग्राम शुरू करता है (यानी कॉल प्रोग्राम, कॉन्फ़िगर चर, आदि प्रदान करता है)।

क्या कोई तरीका है कि मैं प्रक्रियाओं को साफ तरीके से बंद कर सकता हूं? मैं सोच रहा था कि एक घटना होने पर जिसे मैं प्रक्रिया को मारना चाहता हूं, काम कर सकता है लेकिन अब तक मैं उस विचार को काम करने में सक्षम नहीं हूं क्योंकि मैं यह निर्दिष्ट करने में असमर्थ हूं कि मैं कौन सी प्रक्रिया बंद करना चाहता हूं।

** संपादित करें - इवेंट हैंडलिंग के लिए मेरा कोड जिसे मैंने प्रत्यारोपण करने का प्रयास किया है लेकिन यह काम नहीं कर रहा है।

कोड मुख्य रूप से खिड़की

public void KillOne() { 
    foreach (var details in _runs.Values) { 
     if(details.IsSelected) { 
      StrategyStateManager.SessionClosed(this, details.RunId); 
       } } } 

StrategyStateManager में कोड (मध्य कार्यक्रम में उपयोग करने के लिए चर और घटनाओं पकड़ इस्तेमाल वर्ग)

प्रक्रिया में
public delegate void StrategyCloseEventHandler(object sender, StrategyCloseEventArgs e); 

    public static void SessionClosed(object sender, Guid id) 
    { 
     if(CloseSession != null) 
      CloseSession(sender, new StrategyCloseEventArgs(id)); 
    } 


public class StrategyCloseEventArgs : EventArgs 
{ 

    private readonly Guid id; 

    public StrategyCloseEventArgs(Guid run_id) 
    { 
     id = run_id; 
    } 

    public Guid GetRunID() 
    { 
     return id; 
    } 

} 

कोड है कि मुख्य विंडो

द्वारा शुरू किया जा रहा है
StrategyStateManager.CloseSession += (closeStrategy); 

void closeStrategy(object sender, StrategyCloseEventArgs e) 
    { 
     if (e.GetRunID() == run_id) 
     { 
      strategy.cleanupForShutdown(); 
      DBSaverSimple.shutdownAll(); 
      logger.Warn("Simulation run stopped by user"); 
     } 
    } 

उत्तर

4

संभावित रूप से दिमाग में आने वाली संभावना एक प्रसारण डेटाग्राम का उपयोग करना है जिसमें एक करीबी संदेश और उस प्रक्रिया की आईडी आईडी है जिसे आप बंद करना चाहते हैं। प्रत्येक कंसोल प्रक्रिया एक सामान्य बंदरगाह पर प्रसारण डेटाग्राम के लिए सुनती है। जब कार्यक्रम डेटाग्राम प्राप्त करता है, तो यह डेटा को पार करता है, पास की प्रक्रिया आईडी को अपनी प्रक्रिया आईडी के विरुद्ध जांचता है, और यदि वे मेल खाते हैं, तो प्रोग्राम एक साफ शटडाउन शुरू करता है।

यह मानता है कि आपने प्रोग्राम को साफ तरीके से बंद करने का एक तरीका बनाया है।

ब्रॉडकास्ट डेटाग्राम को निश्चित रूप से प्राप्त करने की गारंटी नहीं है, लेकिन मेरा अनुभव यह है कि वे एक सिस्टम पर भरोसेमंद हैं। यदि आप किसी समस्या में भाग लेते हैं, तो आप अपना मुख्य प्रोग्राम डेटाग्राम भेज सकते हैं, यह देखने के लिए कुछ समय प्रतीक्षा करें कि प्रोग्राम बंद हो गया है, और यदि नहीं, तो फिर डेटाग्राम भेजें।

एक और संभावना है कि आप शुरू की गई प्रत्येक प्रक्रिया के लिए नाम EventWaitHandle बनाएं, उस घटना का नाम कमांड लाइन पर कंसोल एप्लिकेशन पर पास कर दें। कंसोल प्रोग्राम में तब एक थ्रेड हो सकता है जो उस घटना पर WaitOne करता है। जब ईवेंट सेट किया जाता है, तो प्रोग्राम एक साफ शटडाउन शुरू करता है। यह प्रसारण डेटाग्राम से अधिक विश्वसनीय है। निश्चित रूप से, यह प्रति प्रक्रिया एक और हैंडल का उपयोग करता है, लेकिन यह तब तक कोई समस्या नहीं होगी जब तक आपके पास हजारों प्रक्रियाएं न हों।

प्रक्रियाओं के बीच संवाद करने के लिए नामित प्रतीक्षा संभाल का उपयोग करने के उदाहरण के लिए Send message from one running console app to another देखें।

+0

दिखाने के लिए मूल प्रश्न संपादित किया है, मैंने आपके द्वारा सुझाए गए EventWaitHandle Idea को लागू किया है और यह बहुत अच्छा काम करता है। धन्यवाद – jwb555

+0

डाउनवॉटर? डाउनवोट के लिए एक कारण देने के लिए एक टिप्पणी प्रदान करना प्रथागत है। –

1

ऐसा लगता है जैसे आप अपने अलग में एक निश्चित स्थिति प्राप्त करने जा रहे हैं उप-प्रक्रियाओं द्वारा कोड को चलाया जा रहा है जिस बिंदु पर आप उस प्रक्रिया को समाप्त करना चाहते हैं। आप कोड कोड के अंत में Process.GetCurrentProcess().Kill(); या यहां तक ​​कि Process.GetCurrentProcess().Close(); पर कॉल क्यों नहीं करते?

इस तरह जब इसे निष्पादित किया जाता है तो यह बंद हो जाएगा/खुद को मार देगा और शेष प्रक्रियाएं तब तक चलती रहेंगी जब तक कि वे फिट न हों (जब तक वे भी उनके समापन बिंदु तक नहीं पहुंच जाते)?

+0

मेरे पास कोड में एक निश्चित समय नहीं है जब मैं इसे समाप्त करना चाहता हूं। एक बटन द्वारा समाप्ति का निर्णय जीयूआई में क्लिक किया जाता है। यदि मैं Process.Kill() का उपयोग करता हूं तो यह प्रोग्राम को समाप्त कर देगा और क्लीन क्लोज़ और प्रोसेस नहीं करेगा। क्लोज़() वास्तव में प्रक्रिया को समाप्त नहीं करता है, यह केवल प्रक्रिया, और संबंधित संसाधनों पर "स्थानीय" दृश्य को रिलीज़ करने के लिए है। – jwb555

+0

क्या आपने वास्तव में 'प्रक्रिया की कोशिश की है। बंद करें WinWindow() '? यदि यह एक बटन प्रेस से आ रहा है, तो आपके पास निश्चित रूप से मुख्य विंडो है। आप आवेदन को बंद करने के लिए 'System.Exit()' भी कोशिश कर सकते हैं। यदि उप-प्रक्रिया में कहा जाता है तो मैं * विश्वास करता हूं * यह आपको वह देगा जो आप चाहते हैं। – Kevek

+0

समाप्ति जीयूआई से आ रही है लेकिन वास्तविक प्रक्रिया में प्रक्रिया शुरू करने के लिए teh कमांड प्रॉम्प्ट में परिभाषित कोई खिड़की नहीं है। इस प्रक्रिया के कारण। CloseMainWindow() प्रक्रिया के लिए कुछ भी नहीं करता है। सिस्टम.एक्सिट() इसे बंद करने के लिए काम करेगा, लेकिन मुझे इसे एक विशिष्ट प्रक्रिया में कॉल करने में सक्षम होने का एक तरीका चाहिए क्योंकि एक ही समय में एकाधिक चल रहे होंगे, इसलिए सिस्टम को कॉल करने के लिए कोई ईवेंट या कुछ अन्य अधिसूचना की आवश्यकता होगी .xit(), जिसे मैं कई प्रक्रिया स्थिति के कारण अब तक प्रत्यारोपण करने में असमर्थ रहा हूं। – jwb555

संबंधित मुद्दे