Студопедия КАТЕГОРИИ: АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Работа с прямоугольной областью ⇐ ПредыдущаяСтр 2 из 2
Для задания координат и размера прямоугольника необходимо добавить в класс формы соответствующую переменную типа Rectangle:
Rectangle rect = new Rectangle(180, 110, 150, 100);
Рисование прямоугольника производится в обработчике события Paint формы:
Private void Form1_Paint(object sender, PaintEventArgs e) { //получаем контекст устройства Graphics g = e.Graphics; //создаем черную кисть Brush b = Brushes.Black; //рисуем прямоугольник g.FillRectangle(b, rect); }
Если на этом этапе запустить программу, то можно увидеть, как круги, проходя сквозь прямоугольник, «стирают» на своем пути часть его. Это происходит из-за того, что при реализации движения круг «стирается» путем заливки его цветом формы. Устранить данный эффект можно путем перерисовки прямоугольника при попадании круга внутрь него. Таким образом, в методе MoveCircle() после строчки Thread.Sleep(30); следует добавить следующее:
//если круг или его часть - внутри прямоугольника, if (y + 10 > rect.Y && y - 10 < rect.Y + rect.Height) //то перерисовываем прямоугольник Invalidate();
Синхронизация потоков Так как в данной программе необходимо обеспечить управление доступом потоков (кругов) к общему ресурсу (прямоугольнику), то, прежде всего, нужно обеспечить блокировку объекта с помощью метода lock(). Эта блокировка должна действовать, только если один из кругов находится внутри прямоугольника, иначе блокировку нужно снять (метод Wait() класса Monitor) и уведомить об этом второй поток (метод Pulse() класса Monitor). Также для корректного завершения работы потоков необходимо вызвать метод Pulse() при завершении работы потока. Таким образом, окончательный вариант метода MoveCircle() будет выглядеть следующим образом:
Private void MoveCircle() { //устанавливаем блокировку метода lock (this) { //создаем контекст устройства 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); //если круг или его часть - внутри прямоугольника, if (y+10 > rect.Y && y - 10 < rect.Y + rect.Height) //то перерисовываем прямоугольник Invalidate(rect); else { //разрешаем выполнение другого потока Monitor.Pulse(this); //ждем приостановки/завершения другого потока Monitor.Wait(this); } //стираем круг g.FillEllipse(b2, x - 10, y - 10, 20, 20); } //выводим поток из режима ожидания Monitor.Pulse(this); } //проверяем корректность завершения потока MessageBox.Show("Поток " + Thread.CurrentThread.Name + " завершен!"); }
Задание для самостоятельной работы Модифицировать данную программу следующим образом: - приложение должно быть основано на многодокументном интерфейсе; - вся работа с потоками (движение круга) должна производиться в дочернем окне; - увеличить количество потоков в каждом дочернем окне до трех; - в каждом дочернем окне должно быть два прямоугольника, круги (потоки) должны «проходить сквозь них» последовательно; - круги должны двигаться горизонтально.
|
||
Последнее изменение этой страницы: 2018-06-01; просмотров: 283. stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда... |