Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
LR_8_Tekhnologia_programmirovania.docx
Скачиваний:
72
Добавлен:
20.03.2016
Размер:
41.27 Кб
Скачать

3. Пример выполнения работы

Задание. Необходимо разработать многопоточное приложение с синхронизацией двух потоков и управлением доступом к общему ресурсу. В каждом потоке осуществляется движение графического объекта (в данном случае, круга) от верхнего края формы к нижнему, после чего потоки завершаются. В качестве общего ресурса выступает прямоугольная область в середине формы. Необходимо скоординировать потоки таким образом, чтобы в каждый момент времени внутри этой области находился только один круг.

Внешний вид работающего приложения приведен на рисунке 8.1.

Рис. 8.1. Пример работающего приложения

3.1. Создание потоков

Прежде всего, для работы с потоками необходимо подключить пространство имен System.Threading.

Для того чтобы создавать в приложении новые потоки, необходимо задать метод, который будет являться точкой входа в поток. Этот метод должен быть типа void и без параметров. В нашем случае именно в этом методе (который здесь назван MoveCircle()) и будет осуществляться движение круга.

В этом методе сначала создается контекст графического устройства и две кисти: одна (красного цвета) для круга, вторая (цвета формы) – для стирания предыдущего изображения круга.

Чтобы два круга в разных потоках не сливались друг с другом, для них указываются разные координаты x. Значения координаты устанавливаются в зависимости от имени потока (свойство Name).

После этого в цикле, пока не достигнут нижний край формы, рисуется очередной круг, поток на некоторое время приостанавливается (иначе движение будет происходить настолько быстро, что увидеть его просто не получится), а затем круг стирается.

После окончания цикла для корректности выводится сообщение о завершении текущего потока. Листинг метода приведен ниже:

private void MoveCircle()

{

//создаем контекст устройства

Graphics g = this.CreateGraphics();

//создаем красную кисть - для круга

Brush b1 = Brushes.Red;

//и кисть цвета формы - для стирания круга

Brush b2 = SystemBrushes.Control;

int x;

//координата x круга будет зависеть от имени потока

if (Thread.CurrentThread.Name == "First")

x = Width / 2 - 30;

else

x = Width / 2 + 30;

//цикл от верхнего до нижнего края формы

for (int y = 10; y < Height - 40; y++)

{

//рисуем круг

g.FillEllipse(b1, x - 10, y - 10, 20, 20);

//"усыпляем" поток на 30 миллисекунд

Thread.Sleep(30);

//стираем круг

g.FillEllipse(b2, x - 10, y - 10, 20, 20);

}

//проверяем корректность завершения потока

MessageBox.Show("Поток " + Thread.CurrentThread.Name + " завершен!");

}

Непосредственное создание потоков можно выполнять в обработчике события Load главной формы. При этом для каждого потока нужно создать объект класса Thread, указав при этом имя метода, который будет точкой входа в поток. Далее следует присвоить потоку имя и запустить его с помощью метода Start(). Код обработчика приведен ниже:

private void Form1_Load(object sender, EventArgs e)

{

//создаем первый поток

//(точка входа в него - метод MoveCircle())

Thread thread1 = new Thread(new ThreadStart(MoveCircle));

//присваиваем потоку имя

thread1.Name = "First";

//аналогично для второго потока

Thread thread2 = new Thread(new ThreadStart(MoveCircle));

thread2.Name = "Second";

//запускаем оба потока

thread1.Start();

thread2.Start();

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]