5

मैं एक कमांड लाइन आवेदन पृष्ठभूमि, यहाँ डाउनलोड किया जा सकता है, जो नियंत्रित करने के लिए सी # का उपयोग करने के कोशिश कर रहा हूँ पर कार्य प्रगति पर है: http://www.ti.com/litv/zip/spmc015bअपवाद पहले से ही StandardOutput धारा

यह मोटर वोल्टेज के लिए एक ऐप है नियंत्रण, जब मैं ऐप दर्ज करता हूं, जैसे "b.exe -c 1", कंसोल एक प्रकार का अवरोधक मॉडल लगता है। इस ऐप में प्रत्येक कमांड "#" प्रतीक से शुरू होता है। यहाँ तस्वीरें देखें:

http://i46.tinypic.com/zx5edv.jpg

मुझे क्या करना, StandardInput.WriteLine ("स्टेट vout") का उपयोग कर रहा है कोशिश कर रहा हूँ; वोल्टेज को मापने के लिए। यह कंसोल पृष्ठभूमि में "स्टेट vout" कमांड भेज देगा और आदर्श रूप से वोल्टेज मान लौटाएगा। इस तस्वीर में, यह कुछ मदद संकेत देता है। इस बार ड्यूइंग, यह अभी भी अवरुद्ध मोड में है।

मैं मानकऑटपुट के साथ रिटर्न संदेश प्राप्त करना चाहता हूं। रीडलाइन(); परंतु विफल हो गया। यदि ReadToEnd() तो मेरा प्रोग्राम फ्रीज हो गया है क्योंकि यह ऐप कभी भी मानक कंसोल पर वापस नहीं आ रहा है, जो अवरुद्ध है।

जब मैंने BeginOutputReadLine() की कोशिश की; OutputDataReceived घटना वास्तव में कंसोल से संदेश वापसी प्राप्त कर सकती है, जैसे "stat [vout | vbus | fault" की तस्वीरों में। लेकिन यह मेरे एकल थ्रेड कार्यक्रम में सीमित है।

मेरी वर्तमान स्थिति यह है कि, मैं WinForms में System.Timers.Timers का उपयोग करता हूं और प्रत्येक सेकेंड वोल्टेज पढ़ने के लिए "stat vout2" कमांड भेजता है, और उम्मीद है कि वापसी मूल्य प्राप्त होगा।

हालांकि, सिस्टम.Timers.Timers एसिंक्रोनस है, इसलिए जब मैंने इस टाइमर थ्रेड में BeginOutputReadLine() कहा, तो यह संकेत दिया गया कि "स्ट्रीम पर एक एसिंक रीड ऑपरेशन पहले ही शुरू हो चुका है।" इस बीच, जैसा कि मैंने ऊपर दिखाया है, मैं मान प्राप्त करने के लिए रीडलाइन() जैसे सिंक्रोनस विधियों का उपयोग नहीं कर सकता।

तो अब मुझे क्या करना चाहिए? मुझे वास्तव में बहु-थ्रेडिंग मोड में यह कमांड लाइन ऐप चलाने की आवश्यकता है।

बहुत बहुत धन्यवाद और सभी की इच्छा है कि सप्ताहांत अच्छा रहे।

WinFroms बटन शुरू होगा में से एक() SystemClock क्लास, तो Timing.Measuring() हर दूसरे निष्पादित होने पर अप्रैल 28 19:18 सीएसटी

--UPDATE यहाँ प्रासंगिक स्रोत कोड है। टाइमकंट्रोलर क्लास वोल्टेज और वर्तमान को मापने के लिए सिस्टमक्लॉक के अनुसार एक सेकंड के दौरान GetVoltage() और GetCurrent() को एक ही समय में कॉल करेगा।

मापने वर्ग में, StandardInput.WriteLine ("stat vout2"); कंसोल ऐप से वोल्टेज प्राप्त करने के लिए, और StandardInput.WriteLine ("स्टेट cur"); वर्तमान प्राप्त करने के लिए। मानक आउटपुट काम नहीं करने के बाद से दोनों परिणाम प्राप्त करने के लिए BeginOutputReadLine() का उपयोग करते हैं।

मैं डेटा आउटपुट के संकेत देने के लिए एक isOutputObtained ध्वज का उपयोग करता हूं। हर बार पढ़ना समाप्त हो जाता है, मैंने CancelOutputRead() को कॉल किया था; एसिंक्रोनस पढ़ने को रद्द करने के लिए।

लेकिन यह अभी भी मुझे

public class SystemClock 
{ 
    TimingController Timing = new TimingController(); 
    private Timer TimerSystemClock; 

    public SystemClock() 
    { 
     TimerSystemClock = new Timer(); 
     TimerSystemClock.Interval = 1000; 
     TimerSystemClock.AutoReset = true; 
     TimerSystemClock.Elapsed += new ElapsedEventHandler(TimerSystemClock_Elapsed); 
     TimerSystemClock.Enabled = false; 
     Timing.ClockInstance = this; 
    } 

    public void Start() 
    { 
     TimerSystemClock.Enabled = true; 
    } 

    void TimerSystemClock_Elapsed(object sender, ElapsedEventArgs e) 
    { 
     Timing.Measuring(); 
    } 
} 

public class TimingController 
{ 
    // Get singleton of Measurement Class 
    Measurement Measure = Measurement.GetInstance();  

    public SystemClock ClockInstance 
    { 
     get { return Clock; } 
     set { Clock = value; } 
    } 

    private void Measuring() 
    { 
     CurrentVoltage = Measure.GetVoltage(); 
     CurrentCurrent = Measure.GetCurrent(); 
    } 
} 

public sealed class Measurement 
{ 
    // Singleton 
    public static readonly Measurement instance = new Measurement(); 
    public static Measurement GetInstance() 
    { 
     return instance; 
    } 

    private Process ProcMeasuring = new Process(); 
    double measureValue 
    bool isOutputObtained; 

    private Measurement() 
    { 
     ProcMeasuring.StartInfo.FileName = "b.exe"; 
     ProcMeasuring.StartInfo.Arguments = "-c 1"; 
     ProcMeasuring.StartInfo.WorkingDirectory = Directory.GetCurrentDirectory(); 
     ProcMeasuring.StartInfo.UseShellExecute = false; 
     ProcMeasuring.StartInfo.RedirectStandardInput = true; 
     ProcMeasuring.StartInfo.RedirectStandardOutput = true; 
     ProcMeasuring.StartInfo.RedirectStandardError = true; 
     ProcMeasuring.StartInfo.CreateNoWindow = true; 
     ProcMeasuring.OutputDataReceived += new DataReceivedEventHandler(MeasurementOutputHandler); 
    } 

    public double GetVoltage(Machine machine) 
    { 
     isOutputObtained = false; 

     ProcMeasuring.StandardInput.WriteLine("stat vout2"); 
     ProcMeasuring.BeginOutputReadLine(); 

     while (!isOutputObtained) 
     { 
      isOutputObtained = true; 
     } 

     return measureValue; 
    } 

    public double GetCurrent(Machine machine) 
    { 
     isOutputObtained = false; 

     ProcMeasuring.StandardInput.WriteLine("stat cur"); 
     ProcMeasuring.BeginOutputReadLine(); 

     while (!isOutputObtained) 
     { 
      isOutputObtained = true; 
     } 

     return measureValue; 
    } 

    private void MeasurementOutputHandler(object sendingProcess, DataReceivedEventArgs outLine) 
    { 
     if (!String.IsNullOrEmpty(outLine.Data) && (outLine.Data != "# ")) 
     {     
      measureCurrentValue = Convert.ToDouble(outLine.Data); 
      isOutputObtained = true; 

      ProcMeasuring.CancelOutputRead(); 
     } 
    } 
} 
+0

कुछ रिलीज कोड पोस्ट करने से मदद मिल सकती है। –

+0

मेरा कोड बहुत लंबा है, मैं इसे एक नए उत्तर के रूप में दिखाऊंगा – Asker

+1

नहीं, यह कोई जवाब नहीं है। इसे प्रश्न में रखो। –

उत्तर

0

की "एक अतुल्यकालिक पढ़ने आपरेशन StandardOutput धारा पर पहले से चल रही है" त्रुटि अपवाद दे मुझे लगता है कि आप दो विकल्प हैं।

यदि नमूना याद करना ठीक है क्योंकि पिछला एक बहुत लंबा समय लेता है, तो यह इंगित करने के लिए एक ध्वज सेट करें कि आप पहले ही नमूना कर रहे हैं।

public class TimingController 
{ 
    // Get singleton of Measurement Class 
    Measurement Measure = Measurement.GetInstance();   

    bool isMeasuring = false; 

    public SystemClock ClockInstance 
    { 
     get { return Clock; } 
     set { Clock = value; } 
    } 

    private void Measuring() 
    { 
     if(isMeasuring) return; 

     isMeasuring = true; 
     CurrentVoltage = Measure.GetVoltage(); 
     CurrentCurrent = Measure.GetCurrent(); 
     isMeasuring = false; 
    } 
} 

तो यह ठीक एक अंतराल को याद नहीं है, तो आप प्रत्येक कॉल के लिए एक नई प्रक्रिया वस्तु बनाने के बजाय मौजूदा प्रक्रिया को पुन: उपयोग की कोशिश कर सकते। यह बहुत सारे बच्चे पैदा कर सकता है हालांकि आदेशों को पूरा करने में लंबा समय लगता है।