Я разрабатываю C # WFA, который позволяет мне делать некоторые вещи с помощью программного обеспечения для химии: GAMESS.По сути, у меня есть командный файл, который при выполнении с соответствующими аргументами возвращает файл с данными, необходимыми для атомарного анализа.
В форме приложения я установил текстовое поле только для чтения с выводом процесса.Я сделал это, изменив стандартный вывод.Это чтение выполняется синхронно.Работает хорошо для небольших выходов, но много раз, когда линии weeldes 240k.Мой процесс автоматически закрывается по окончании (последняя инструкция «EXIT», а не «EXIT / B»).Как вы (вероятно) выяснили, основная форма становится нестабильной и не допускает никакого пользовательского ввода, пока процесс не завершится.Это проблема ...
Я пробовал асинхронное чтение FileStream для другой функции в моем коде и работал очень хорошо, но я застрял в том, что касается StandardOutput.Я не могу найти правильный способ сделать это.
Вот мой код:
private void Button1_Click(object sender, EventArgs e)
{
if (!String.IsNullOrEmpty(Input_job_file) && !String.IsNullOrEmpty(Log_file))
{
textBox3.Text = "Executing code...\r\n";
string outtext;
string batpath = string.Format(Settings.Default.path_to_gamess + "\\rungms.bat");
string arguments = string.Format("{0} {1} {2} 0 {3}", Input_job_file, Settings.Default.version, Ncpus, Log_file);
//Here we need to copy the input file to the gamess directory in order to avoid errors
File.Copy(Input_job_file, Settings.Default.path_to_gamess + "\\" + FileNameWithoutExtension + ".inp");
Process gamessjob = new Process();
gamessjob.StartInfo.ErrorDialog = true;
gamessjob.StartInfo.UseShellExecute = false;
gamessjob.StartInfo.CreateNoWindow = true;
gamessjob.StartInfo.RedirectStandardOutput = true;
gamessjob.StartInfo.RedirectStandardError = true;
gamessjob.EnableRaisingEvents = true;
gamessjob.StartInfo.WorkingDirectory = Settings.Default.path_to_gamess;
gamessjob.StartInfo.FileName = batpath;
gamessjob.StartInfo.Arguments = arguments; //input_file, version, number_of_processors, "0", output_name]
gamessjob.Start();
//STDOUT redirection to our textbox in readonly mode
outtext = gamessjob.StandardOutput.ReadToEnd();
textBox3.Text += outtext + "\r\nProcess executed!";
//here we clean up some stuff after GAMESS code ends
File.Delete(Settings.Default.path_to_gamess + "\\" + FileNameWithoutExtension + ".inp");
MessageBox.Show("Code executed!\nCheck output for errors or messages.", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else MessageBox.Show("Input file and/or output location is invalid!", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
//ASYNC
byte[] result;
textBox6.Text = "Executing code...\r\n\n";
using (FileStream SourceStream = File.Open(Input_dat_file, FileMode.Open))
{
result = new byte[SourceStream.Length];
await SourceStream.ReadAsync(result, 0, (int)SourceStream.Length);
}
В идеале чтение перенаправленного стандартного вывода в асинхронном режиме должно решить тупик моего приложения (верно?) или хотя бы сократить его продолжительность.Возможно, если я сделаю это с ReadLineAsync () вместо ReadToEndAsync (), текстовое поле будет обновляться чаще и, следовательно, будет более «приятным» для просмотра.Я искал учебники для асинхронных операций, но все они показывают файловые операции.Поиск в справочнике Microsoft по стандартному перенаправлению вывода и асинхронности еще больше сбивает меня с толку.
Может кто-нибудь помочь мне найти способ читать выходные данные построчно с помощью ReadLineAsync ()?