Список используемых источников
В чем разница между мьютексом, монитором и семафором: [Электронный ресурс]. 2019. URL: https://javarush.ru/groups/posts/2174-v-chem-raznica-mezhdu-mjhjuteksom-monitorom-i-semaforom
Работа с потоками в C# : [Электронный ресурс]. 2009. URL: https://www.rsdn.org/article/dotnet/CSThreading2.xml
Лабораторная работа № 3
«Применение вторичных потоков для обслуживания ввода-вывода»
Задание:
Разработать программу, которая для решения одной из подзадач вызывает консольное приложение. Необходимо считывать информацию, которую вызываемое (дочернее) приложение выводит в консоль, и показывать ее в окне приложения. И наоборот, когда дочернему приложению нужен ввод с клавиатуры, мы должны вводить текстовую строку в главном приложении, и эта строка будет отсылаться приложению дочернему. Написать GUI-приложение, предоставляющее поле ввода для указания командной строки, например, «cmd.exe /c dir», кнопку «Пуск» для запуска указанной команды и какой-либо визуальный элемент (список, Memo или что-то в этом роде) для просмотра выводимого запущенной командой текста, а также еще одно поле ввода для ввода текста в дочернее приложение. Не забудьте при пересылке строки текста дочернему приложению добавлять в конец строки символ возврата каретки (символ с кодом 10).
Описание работы приложения:
Лабораторная работа была реализована на языке программирования C#, т. к. он содержит все необходимые классы для реализации поставленной задачи. Было написано серверное приложение, которое представляет из себя форму с полем для ввода команд и окно для вывода результатов. По нажатию кнопки «Ввести в консоль» происходит отправка команды. Было использовано событие Process.OutputDataReceived для записи строки перенаправленный поток.
Пример работы приложения:
Рисунок 3 - Пример работы программы
Листинг программы:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Windows.Forms;
namespace RTS_Laba_3
{
public partial class Form1 : Form
{
Process console;
StreamWriter writer;
public Form1()
{
InitializeComponent();
console = Process.Start(new ProcessStartInfo("cmd.exe")
{
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true
});
// Задание обработчика вывода
console.OutputDataReceived += OutputHandler;
// Начать перехват вывода в обработчик
console.BeginOutputReadLine();
// поток ввода
writer = console.StandardInput;
writer.AutoFlush = true;
}
private void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
if (!String.IsNullOrEmpty(outLine.Data))
{
textBox2.Invoke(new Action(() =>
{
if (outLine.Data == "\f")
{
textBox2.Text = "";
return;
}
// получаем байты строки из текущей кодировки (win1251) (которая cp866)
var bytes = Encoding.Default.GetBytes(outLine.Data);
// декодируем байты в CP866 кодировке
var text = Encoding.GetEncoding("CP866").GetString(bytes);
textBox2.Text += text + "\r\n";
}));
}
}
private void EnterCommand()
{
// пишем в поток ввода дочернего процесса
writer.WriteLine(textBox1.Text + "\r\n");
textBox1.Text = "";
}
private void button1_Click(object sender, EventArgs e)
{
EnterCommand();
}
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.Enter)
{
EnterCommand();
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
console.Close();
}
private void button2_Click(object sender, EventArgs e)
{
writer.WriteLine("cls\r\n");
}
}
}
Вывод:
В ходе выполнения данной лабораторной работы были получены навыки применения потоков для работы с каналами ввода-вывода, а также разработано приложение, считывающее поток вывода и записывающего в поток ввода дочернего приложения.