Я пытаюсь использовать C# для управления фоном приложения командной строки, которую можно скачать здесь: http://www.ti.com/litv/zip/spmc015bИсключения асинхронной операции чтения уже идут на потоке StandardOutput
Это приложение для напряжения двигателя когда я вхожу в приложение, например «b.exe -c 1», консоль кажется своего рода блокирующей моделью. Каждая команда в этом приложении начинается с символа «#». Смотрите фотографии здесь:
http://i46.tinypic.com/zx5edv.jpg
То, что я пытаюсь сделать, это использовать StandardInput.WriteLine ("стат Vout"); для измерения напряжения. Это отправит команду «stat vout» на фон консоли и в идеале вернет значение напряжения. В этой статье он возвращает подсказки. Дуинг все это время, он все еще находится в режиме блокировки.
Я хочу получить обратное сообщение с помощью StandardOutput.ReadLine(); но не удалось. Если ReadToEnd(), то моя программа зависает, потому что это приложение никогда не возвращается к стандартной консоли, которая блокирует.
Когда я попробовал BeginOutputReadLine(); Событие OutputDataReceived может действительно получить возврат сообщения с консоли, как в pics of stat [vout | vbus | fault ». Но он ограничен в моей программе с одним потоком.
Моя нынешняя ситуация в том, что я использую System.Timers.Timers в WinForms и каждую секунду отправит команду «stat vout2» для чтения напряжения и, надеюсь, получит возвращаемое значение.
Однако System.Timers.Timers является асинхронным, поэтому, когда я вызывал BeginOutputReadLine() в этом потоке таймеров, он запрашивал: «В потоке уже запущена операция чтения async». Тем временем, как я показал выше, я не могу использовать синхронные методы, такие как ReadLine(), чтобы получить значение.
Итак, что мне теперь делать? Мне действительно нужно запустить это приложение командной строки в многопоточном режиме.
Большое спасибо и пожелайте всем приятного уик-энда.
--update 28 апреля 19:18 CST Вот соответствующий исходный код:
Один из WinFroms кнопка Пуск() для SystemClock класса, то Timing.Measuring() выполняется каждый второй. Класс TimingController вызовет GetVoltage() и GetCurrent() одновременно в течение одной секунды в соответствии с SystemClock для измерения напряжения и тока.
В измерительном классе, 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();
}
}
}
Проводка некоторых из приведенных выше кодов может помочь. –
Мой код слишком длинный, я покажу его как новый ответ – Asker
Нет, это не ответ. Поместите это в вопрос. –