我試圖用C#來控制命令行應用程序的背景,這可以在這裏下載進度:http://www.ti.com/litv/zip/spmc015b異常異步讀操作的已經在上StandardOutput流
這是電動機電壓的應用控制,當我進入應用程序,如「b.exe -c 1」,控制檯似乎是一種阻塞模型。此應用程序中的每個命令都以「#」符號開頭。見圖片瀏覽:
http://i46.tinypic.com/zx5edv.jpg
我想要做的是,用StandardInput.WriteLine( 「STAT VOUT」);測量電壓。這將向控制檯背景發送一個「stat vout」命令,並理想地返回一個電壓值。在這張照片中,它會返回一些幫助提示。 Duing這一次,它仍然處於阻塞模式。
我想與StandardOutput.ReadLine返回消息();但失敗了。如果ReadToEnd()那麼我的程序被凍結,因爲這個應用程序永遠不會返回到阻塞的標準控制檯。
當我試圖BeginOutputReadLine(); OutputDataReceived事件可以真正從控制檯獲得消息返回,如在「stat [vout | vbus | fault」的圖片中。但它限制在我的單線程中。
我現在的情況是,我使用System.Timers.Timers在WinForms和每一秒就會發出「STAT VOUT2」命令來讀取電壓,並希望得到返回值。
但是,System.Timers.Timers是異步的,所以當我在此定時器線程中調用BeginOutputReadLine()時,它提示「異步讀操作已在流上啓動」。同時,正如我上面演示的那樣,我不能使用像ReadLine()這樣的同步方法來獲取值。
那麼應該怎麼辦?我真的需要在多線程模式下運行這個命令行應用程序。
非常感謝,祝大家有一個愉快的週末。上04月28日19時18分CST
--update下面是相關的源代碼:
其中WinFroms按鈕將啓動()的SystemClock類,然後Timing.Measuring()被執行每一秒。根據SystemClock,TimingController類將在一秒鐘內同時調用GetVoltage()和GetCurrent(),以測量電壓和電流。
在測量類中,StandardInput.WriteLine(「stat vout2」);從控制檯應用程序獲取電壓,以及StandardInput.WriteLine(「stat cur」);獲取最新資訊。他們都使用BeginOutputReadLine()來獲得結果,因爲StandardOutput不起作用。
我用isOutputObtained標誌與表示,如果返回的數據。每次閱讀完成後,我確實調用了CancelOutputRead();取消異步讀取。
但它仍然給我的「異步讀操作已在StandardOutput流進步」
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();
}
}
}
發佈一些相關的代碼可能會有所幫助。 – 2012-04-28 09:29:04
我的代碼太長,我會將其作爲新答案顯示 – Asker 2012-04-28 22:10:52
不,這不是一個答案。把它放在問題上。 – 2012-04-28 22:33:04