ここでダウンロードできるコマンド ライン アプリケーションのバックグラウンドを制御するために C# を使用しようとしています: http://www.ti.com/litv/zip/spmc015b
これはモーター電圧制御用のアプリです。「b.exe -c 1」のようにアプリに入ると、コンソールは一種のブロック モデルのように見えます。このアプリのすべてのコマンドは「#」記号で始まります。ここで写真を見てください:
http://i46.tinypic.com/zx5edv.jpg
私がやろうとしているのは、StandardInput.WriteLine("stat vout"); を使用することです。電圧を測定します。これにより、「stat vout」コマンドがコンソール バックグラウンドに送信され、理想的には電圧値が返されます。この写真では、いくつかのヘルプ ヒントが返されます。この間ずっと、まだブロッキングモードです。
StandardOutput.ReadLine(); で戻りメッセージを取得したい しかし失敗しました。ReadToEnd() の場合、このアプリはブロックしている標準コンソールに戻らないため、プログラムがフリーズします。
私が試したとき BeginOutputReadLine(); OutputDataReceived イベントは、「stat [vout|vbus|fault」の写真のように、コンソールから返されるメッセージを真に取得できます。しかし、それは私のシングルスレッドプログラムでは制限されていました.
私の現在の状況は、WinForms で System.Timers.Timers を使用し、毎秒「stat vout2」コマンドを送信して電圧を読み取り、できれば戻り値を取得することです。
ただし、System.Timers.Timers は非同期であるため、この Timers スレッドで BeginOutputReadLine() を呼び出すと、「ストリームで非同期読み取り操作が既に開始されています」というメッセージが表示されました。それまでの間、上で説明したように、ReadLine() のような同期メソッドを使用して値を取得することはできません。
それで、私は今何をすべきですか?このコマンド ライン アプリをマルチスレッド モードで実行する必要があります。
どうもありがとうございました。皆さんが良い週末を過ごせますように。
--4 月 28 日 19:18 CST の更新: 関連するソース コードは次のとおりです。
WinFroms ボタンの 1 つは SystemClock クラスを Start() し、Timing.Measuring() が毎秒実行されます。TimingController クラスは、電圧と電流を測定するために、SystemClock に従って 1 秒間に GetVoltage() と GetCurrent() を同時に呼び出します。
測定クラスでは、StandardInput.WriteLine("stat vout2"); コンソールアプリから電圧を取得し、StandardInput.WriteLine("stat cur"); 電流を取得します。StandardOutput が機能しなかったため、どちらも BeginOutputReadLine() を使用して結果を取得します。
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();
}
}
}