Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
КОП-Примеры / Приложение 1.doc
Скачиваний:
15
Добавлен:
12.03.2015
Размер:
220.67 Кб
Скачать

Библиотека csContrlRegion.Dll

///////////////

// C# File csContrlRegion Компонент ContrlRegion

using System;

using System.Threading;

using System.Windows.Forms;

namespace csContrlRegionDll

{

// Компонент ContrlRegion

public class ContrlRegion: UserControl

{

Mutex mutex; // Ссылка на объект мютекса

// Конструктор

public ContrlRegion ( )

{

mutex= new Mutex ( );

}

// Свойство Semaphore

public Mutex Semaphore

{

get { return mutex;}

}

}

}

Библиотека csLorry.Dll

///////////////

// C# File csLorry Компонент Lorry

using System;

using System.Threading;

using System.Drawing;

using System.ComponentModel;

using System.Windows.Forms;

using csWarehouseDll;

using csContrlRegionDll;

namespace csLorryDll

{

// Компонент Lorry

public class Lorry : Component

{

int number; // Номер объекта компонента

Point p; // Координаты объекта компонента

int dX; // Приращение координаты Х

bool leftRight; // Направление перемещения груза

ContrlRegion region; // Ссылка на зону контроля

bool inContrl; // Признак нахождения в зоне контроля

Random rand; // Ссылка на объект случайного числа

bool life; // Признак жизни потока

bool run; // Признак выполнения потока

Thread thr; // Ссылка на объект потока

int timePeriod= 100; // Временной интервал перемещения

Warehouse leftWH; // Ссылка на левый склад

Warehouse rightWH; // Ссылка на правый склад

// Конструктор

public Lorry (int Number, int Y, int DX, Warehouse LeftWH,

Warehouse RightWH,ContrlRegion Region)

{

number= Number; dX= DX; leftRight= true; life= false;

run= false; leftWH= LeftWH; rightWH= RightWH;

region= Region; inContrl= false; p= new Point ( );

p.X= leftWH.Location.X+leftWH.Width + 1; p.Y= Y;

rand= new Random ( );

// Создать объект потока

thr= new Thread (new ThreadStart (Moving));

}

// Свойство Number

public int Number { get {return number;}}

// Свойство Point

public Point Point { get {return p;}}

// Свойство LeftRight

public bool LeftRight

{

set {leftRight= value;}

get {return leftRight;}

}

// Стартовать поток

public void Start ( )

{

life= true; run= true;

thr.Start ( );

}

// Завершить поток

public void Finish ( ) {life= false; thr.Join ( );}

// Приостановить поток

public void Stop ( )

{

if (run)

{

run= false;

thr.Suspend ( );

}

}

// Возобновить поток

public void Run ( )

{

if (!run)

{

run= true;

thr.Resume ( );

}

}

// Потоковая функция компонента

private void Moving ( )

{

while (life)

{

// Объект компонента достиг справа

// объекта левого склада

if (p.X <= leftWH.Location.X+leftWH.Width)

{

Console.WriteLine ("Левая граница");

if (leftRight) // Пересылка слева направо

leftWH.Get ( ); // Загрузить груз

else

leftWH.Put ( ); // Выгрузить груз

dX= -dX;

}

// Объект компонента достиг слева

// объекта правого склада

if (p.X >= rightWH.Location.X)

{

Console.WriteLine ("Правая граница");

if (leftRight) // Пересылка слева направо

rightWH.Put ( ); // Выгрузить груз

else

rightWH.Get ( ); // Загрузить груз

dX= -dX;

}

// Обслужить в зоне контроля

Point pR= new Point (region.Location.X,

region.Location.Y);

Rectangle rect= new Rectangle (pR.X, pR.Y, region.Width,

region.Height);

// Вошли в зону контроля

if (rect.Contains (p) && !inContrl) // Вошли в зону

{

Console.WriteLine ("Вошли в зону");

inContrl= true;

// Захватить разделяемый ресурс

region.Semaphore.WaitOne ( );

Thread.Sleep(rand.Next (100, 300));

}

if (!rect.Contains (p) && inContrl) // Вышли из зоны

{

Console.WriteLine ("Вышли из зоны");

inContrl= false;

// Освободить разделяемый ресурс

region.Semaphore.ReleaseMutex ( );

}

Thread.Sleep (timePeriod);

p.X += dX;

}

}

}

}

Приложение csLorryAndWarehouse

///////////////

// C# File csLorryAndWarehouse Приложение csLorryAndWarehouse

// Приложение с компонентами Lorry, Warehouse и с управляющими

// элементами

//

using System;

using System.ComponentModel;

using System.Collections;

using System.Drawing;

using System.Threading;

using System.Windows.Forms;

using csLorryDll;

using csWarehouseDll;

using csContrlRegionDll;

namespace csLorryAndWarehouse

{

// Интерфейс контейнера грузовиков

interface ILorryContainer

{

void AddLorry ( );

void RemoveLorry (int carrNumber);

void RemoveAllLorriers ( );

ArrayList GetNumLorriers ( );

void RunLorriers ( );

void StopLorriers ( );

}

// Контейнер грузовиков

class LorryContainer: Container, ILorryContainer

{

Warehouse leftWH; // Ссылки на объект левого склада

Warehouse rightWH; // Ссылки на объект правого склада

Lorry lorry; // Ссылки на объект грузовика

ContrlRegion region; // Ссылка на объект зоны контроля

bool leftRight; // Признак направления перемещения грузовиков

int numLorry= 0; // Номер грузовика

int Y; // Координата Y пути грузовика

Random rand; // Ссылка на случайное число

// Конструктор

public LorryContainer (Warehouse leftWH, Warehouse rightWH,

ContrlRegion region)

{

this.leftWH= leftWH; this.rightWH= rightWH;

this.region= region;

Y= 20; rand= new Random ( );

leftRight= true;

leftWH.evFromWarehouse += new DelEvFromWarehouse

(this.EvFromWarehouseHandler);

rightWH.evFromWarehouse += new DelEvFromWarehouse

(this.EvFromWarehouseHandler);

}

// Добавить грузовик

public void AddLorry ( )

{

numLorry++;

Y += 20;

int dX = rand.Next (5, 10);

if (leftRight) dX= dX;

else dX= -dX;

lorry= new Lorry (numLorry, Y, dX, leftWH, rightWH,

region);

this.Add (lorry);

lorry.Start ( );

}

// Удалить грузовик

public void RemoveLorry (int lorryNumber)

{

IEnumerator inum= this.Components.GetEnumerator ( );

while (inum.MoveNext ( ))

{

Lorry comp= (Lorry) inum.Current;

if (comp.Number == lorryNumber)

{

comp.Finish ( );

this.Remove (comp);

return;

}

}

}

// Получить список номеров грузовиков

public ArrayList GetNumLorriers ( )

{

ArrayList arList= new ArrayList ( );

IEnumerator inum= this.Components.GetEnumerator ( );

while (inum.MoveNext ( ))

{

Lorry comp= (Lorry) inum.Current;

arList.Add (comp.Number);

}

return arList;

}

// Возобновить движение грузовиков

public void RunLorriers ( )

{

IEnumerator inum= this.Components.GetEnumerator ( );

while (inum.MoveNext ( ))

{

Lorry comp= (Lorry) inum.Current;

comp.Run ( );

}

}

// Приостановить движение грузовиков

public void StopLorriers ( )

{

IEnumerator inum= this.Components.GetEnumerator ( );

while (inum.MoveNext ( ))

{

Lorry comp= (Lorry) inum.Current;

comp.Stop ( );

}

}

// Удалить все грузовики

public void RemoveAllLorriers ( )

{

IEnumerator inum= this.Components.GetEnumerator ( );

while (inum.MoveNext ( ))

{

Lorry comp= (Lorry) inum.Current;

comp.Finish ( );

this.Remove (comp);

}

}

// Выдать номера грузовиков на консоль

public void ShowComponents ( )

{

IEnumerator inum= this.Components.GetEnumerator ( );

while (inum.MoveNext ( ))

{

Lorry comp= (Lorry) inum.Current;

Console.WriteLine("компонент номер " +

comp.Number.ToString ( ));

}

}

// Обработать событие склада

public void EvFromWarehouseHandler (object sender,

WarehouseEventArgs args)

{

leftRight= !leftRight;

IEnumerator inum= this.Components.GetEnumerator ( );

while (inum.MoveNext ( ))

{

Lorry comp= (Lorry) inum.Current;

comp.LeftRight= leftRight;

}

}

}

//-------------------------

class LorryAndWarhouses: Form

{

Warehouse leftWH; // Ссылки на объект левого склада

Warehouse rightWH; // Ссылки на объект правого склада

ContrlRegion region; // Ссылка на объект зоны контроля

Thread thread; // Ссылка но объект потока перерисовки

bool life; // Признок жизни потока перерисовки

Button butRun, butStop; // Ссылки на интерфейсные кнопки

Button butAdd, butDel; // Ссылки на интерфейсные кнопки

ListBox listBox; // Список номеров грузовиков

LorryContainer lorryCont;// Ссылка на контейнер грузовиков

// Конструктор

LorryAndWarhouses ( )

{

this.Text= "Test";

this.ClientSize= new Size (350, 130);

// Создать кнопки

butRun= new Button ( ); // Создать кнопку пуска

butRun.Location= new Point (240,5);

butRun.Size= new Size (45, 20);

butRun.Text= "Run";

butRun.BackColor= Color.LightGray;

butRun.Click += new EventHandler (But_Run);

this.Controls.Add (butRun);

//-----

butStop= new Button ( ); // Создать кнопку останова

butStop.Location= new Point (290,5);

butStop.Size= new Size (45, 20);

butStop.Text= "Stop";

butStop.BackColor= Color.LightGray;

butStop.Click += new EventHandler (But_Stop);

this.Controls.Add(butStop);

//-----

butAdd= new Button ( ); // Создать кнопку добавления butAdd.Location= new Point (240,30);

butAdd.Size= new Size (65, 20);

butAdd.Text= "Добавить";

butAdd.BackColor= Color.LightGray;

butAdd.Click += new EventHandler (But_Add);

this.Controls.Add(butAdd);

butDel= new Button ( ); // Создать кнопку удаления butDel.Location= new Point (240,60);

butDel.Size= new Size (65, 20);

butDel.Text= "Удалить";

butDel.BackColor= Color.LightGray;

butDel.Click += new EventHandler(But_Del);

this.Controls.Add(butDel);

listBox= new ListBox ( ); // Создать элемент списка

listBox.Location= new Point (240, 90);

listBox.Size= new System.Drawing.Size (60, 20);

this.Controls.Add (listBox);

// Создать склады

// Создать объект левого склада

leftWH= new Warehouse (true, true);

leftWH.Location= new Point (10, 10);

leftWH.Size= new Size (30, 100);

leftWH.BackColor= Color.White;

this.Controls.Add (leftWH);

leftWH.Show ( );

// Создать объект правого склада

rightWH= new Warehouse (false, false);

rightWH.Location= new Point (200, 10);

rightWH.Size= new Size (30, 100);

rightWH.BackColor= Color.White;

this.Controls.Add (rightWH);

rightWH.Show ( );

// Создать область контроля

region= new ContrlRegion ( );

region.Location= new Point (100, 0);

region.Size= new Size (40, ClientSize.Height);

region.BackColor= Color.LightSkyBlue;

this.Controls.Add (region);

region.Show ( );

// Создать контейнер компонентов

lorryCont= new LorryContainer (leftWH, rightWH, region); // Создать поток перерисовки и запустить его

life= true;

thread= new Thread(new ThreadStart (ThrPaint));

thread.Start();

}

// Обработать нажатие кнопки пуска

private void But_Run (object o, EventArgs e)

{

lorryCont.RunLorriers ( );

}

// Обработать нажатие кнопки останова

private void But_Stop (object o, EventArgs e )

{

lorryCont.StopLorriers ( );

}

// Обработать нажатие кнопки добавления грузовика

private void But_Add (object o, EventArgs e)

{

lorryCont.AddLorry ( );

lorryCont.ShowComponents ( );

ArrayList aL= new ArrayList ( );

aL= lorryCont.GetNumLorriers( );

listBox.Items.Clear ( );

for (int i= 0; i < aL.Count; i++)

listBox.Items.Add (aL[i]);

}

// Обработать нажатие кнопки удаления грузовика

private void But_Del (object o, EventArgs e )

{

if (listBox.SelectedIndex == -1)

{

MessageBox.Show

("Выберете номер удаляемого грузовика в"

+ "\nэлементе списка перед нажатием кнопки");

}

else

{

int numSel= (int) listBox.SelectedItem;

listBox.Items.Remove (numSel);

lorryCont.RemoveLorry (numSel);

ArrayList aL= new ArrayList ( );

aL= lorryCont.GetNumLorriers ( );

listBox.Items.Clear ( );

for (int i= 0; i < aL.Count; i++)

listBox.Items.Add (aL[i]);

lorryCont.ShowComponents ( );

}

}

// Потоковая функция перерисовки

private void ThrPaint ( )

{

while (life)

{

Invalidate ( );

Thread.Sleep (150);

}

}

// Завершить поток перерисовки

public void Finish ( )

{

life= false; thread.Join ( );

}

// Обработать кнопку закрытия окна

protected override void OnClosed (EventArgs e)

{

base.OnClosed (e);

lorryCont.RemoveAllLorriers ( );

Finish ( );

}

// Перерисовать область клиента прикладного окна

protected override void OnPaint (PaintEventArgs e)

{

base.OnPaint (e);

IEnumerator inum= lorryCont.Components.GetEnumerator ( );

while (inum.MoveNext ( ))

{

Lorry comp= (Lorry) inum.Current;

e.Graphics.DrawEllipse (new Pen(Color.Blue, 2),

comp.Point.X - 10, comp.Point.Y - 10, 20, 20);

e.Graphics.DrawString (comp.Number.ToString ( ), Font,

new SolidBrush (Color.Blue), comp.Point.X + 10,

comp.Point.Y + 10);

}

}

// Основная функция

static void Main ( )

{

Application.Run (new LorryAndWarhouses ( ));

}

}

}

Приложение 2. Программа LorryAndWarehouse с удалённым объектом на языках C++/CLI и C#

Библиотека ccLorry.dll на языке С++/CLI

///////////////

// C++/CLI компонент Lorry

// Поместить библиотеки csWarehouse.dll и csContrlRegion.dll

// в директорий ccLorry\debug

#pragma once

#using <mscorlib.dll>

#using <System.Dll>

#using <System.Drawing.Dll>

#using <System.Windows.Forms.Dll>

#using <..\csWarehouse\bin\debug\csWarehouse.dll>

#using <..\csContrlRegion\bin\debug\csContrlRegion.dll>

using namespace System;

using namespace System::Threading;

using namespace System::Drawing;

using namespace System::ComponentModel;

using namespace System::Windows::Forms;

using namespace csWarehouseDll;

using namespace csContrlRegionDll;

namespace ccLorryDll

{

public ref class Lorry: public Component

{

int number; // Номер объекта компонента

Point p, pR; // Координаты объекта компонента

Rectangle rect; // Прямоугольник зоны контроля

int dX; // Приращение координаты Х

bool leftRight; // Направление перемещения груза

ContrlRegion ^region;// Ссылка на зону контроля

bool inContrl; // Признак нахождения в зоне контроля

Random ^time; // Ссылка на объект случайного числа

bool life; // Признак жизни потока

bool run; // Признак выполнения потока

Thread ^thr; // Ссылка на объект потока

int timePeriod; // Временной интервал перемещения

Warehouse ^leftWH; // Ссылка на левый склад

Warehouse ^rightWH;// Ссылка на правый склад

// Конструктор

public:

Lorry (int Number, int Y, int DX, Warehouse ^LeftWH,

Warehouse ^RightWH, ContrlRegion ^Region)

{

number= Number; // Номер объекта компонента

dX= DX; // Приращение объекта компонента

leftRight= true; // Движение слева направо

timePeriod= 100; // Интервал времени объекта компонента

// Определить прямоугольник зоны контроля

region= Region;

rect.Location= region -> Location;

rect.Width= region -> Width;

rect.Height= region -> Height;

inContrl= false; // Объект вне зоны контроля

time= new Random ( ); // Время задержки в зоне контроля

// Реализовать ссылки на объекты складов

leftWH= LeftWH; rightWH= RightWH;

// Определить левую границу пути для объекта компонента

p.X= leftWH -> Location.X+leftWH -> Width + 1; p.Y= Y;

// Создать объект потока

life= false; run= false;

thr= gcnew Thread (gcnew ThreadStart (this, Moving));

}

// Свойство Number

property int get_Number ( ) {return number;}

// Свойство Point

property Point get_Point ( ) {return p;}

// Свойство LeftRight

property void set_LeftRight (bool leftRight)

{

this -> leftRight= leftRight;

}

property bool get_LeftRight ( )

{

return leftRight;

}

// Стартовать поток

void Start ( )

{

life= true; run= true;

thr -> Start ( );

}

// Завершить поток

void Finish ( ) {life= false; thr -> Join ( );}

// Приостановить поток

void Stop ( )

{

if (run)

{

run= false;

thr -> Suspend ( );

}

}

// Возобновить поток

void Run ( )

{

if (!run)

{

run= true;

thr -> Resume ( );

}

}

private:

// Потоковая функция компонента

void Moving ( )

{

while (life)

{

// Объект компонента достиг справа

// объекта левого склада

if (p.X <= leftWH -> Location.X+leftWH -> Width)

{

Console::WriteLine("Левая граница");

if (leftRight) // Пересылка слева направо

leftWH -> Get(); // Загрузить груз

else

leftWH -> Put(); // Выгрузить груз

dX= -dX;

}

// Объект компонента достиг слева

// объекта правого склада

if (p.X >= rightWH -> Location.X)

{

Console::WriteLine ("Правая граница");

if (leftRight) // Пересылка слева направо

rightWH -> Put( ); //Выгрузить груз

else

rightWH -> Get( ); //Загрузить груз

dX= -dX;

}

// Обслужить в зоне контроля

// Вошли в зону контроля

if (rect.Contains (p) && !inContrl) // Вошли в зону

{

Console::WriteLine ("Вошли в зону");

inContrl= true;

region -> Semaphore -> WaitOne ( );

Thread::Sleep(time -> Next(100, 300));

}

if (!rect.Contains (p) && inContrl) // Вышли из зоны

{

Console::WriteLine ("Вышли из зоны");

inContrl= false;

region -> Semaphore -> ReleaseMutex ( );

}

Thread::Sleep (timePeriod);

p.X += dX;

}

}

};

}

Библиотека ccContrlRegion.dll на языке С++/CLI

///////////////

// C++/CLI Компонент ContrlRegion

#pragma once

#using <mscorlib.dll>

#using <System.Dll>

#using <System.Windows.Forms.Dll>

using namespace System;

using namespace System::Threading;

using namespace System::ComponentModel;

using namespace System::Windows::Forms;

namespace ccContrlRegionDll

{

// Компонент ContrlRegion

public ref class ContrlRegion: public UserControl

{

Mutex ^mutex; // Ссылка на объект мютекса

public:

// Конструктор

ContrlRegion ( )

{

mutex= gcnew Mutex ( );

}

// Свойство Semaphore

property Mutex^ get_Semaphore ( )

{

return mutex;

}

};

}

Библиотека ccWarehouse.dll на языке С++/CLI

///////////////

// C++/CLI компонент Warehouse

#pragma once

#using <mscorlib.dll>

#using <System.Dll>

#using <System.Drawing.Dll>

#using <System.Windows.Forms.Dll>

using namespace System;

using namespace System::Threading;

using namespace System::Drawing;

using namespace System::ComponentModel;

using namespace System::Windows::Forms;

namespace ccWarehouseDll

{

// Класс данных события evFromWarehouse

public ref class WarehouseEventArgs: public EventArgs

{

bool left; // Признак идентификации склада

bool full; // Признак заполненности склада

public:

WarehouseEventArgs (bool left, bool full)

{

this -> left= left; this -> full= full;

}

// Свойство заполнения склада

property bool get_Full ( )

{

return full;

}

// Свойство идентификации склада

property bool get_Left ( )

{

return left;

}

};

// Делегат события о переполнении и опустошении склада

public delegate void DelEvFromWarehouse (Object ^sender,

WarehouseEventArgs *args);

// Интерфейс склада

public interface class IWarehouse

{

void Put ( ); // Поместить груз в склад

void Get ( ); // Получить груз из склада

event DelEvFromWarehouse ^evFromWarehouse; // Ссылка на

// объект события о переполнении и опустошении склада

};

// Компонент склада

public ref class Warehouse: public UserControl,

public IWarehouse

{

bool left; // Признак идентификации склада

int allLoad; // Текущий размер груза в складе

int PartLoad; // Размер груза грузовика

int partLoad; // Получаемая или помещаемая порция груза

int numParts; // Количество порций

int timePeriod; // Время получения или помещения

// порции груза

Thread ^thr; // Ссылка на объект потока

public event DelEvFromWarehouse ^evFromWarehouse; // Ссылка на

// объект события о переполнении и опустошении склада

// Конструктор

Warehouse (bool left, bool full)

{

allLoad= 100; numParts= 5; PartLoad= 10;

this -> left= left; timePeriod= 100;

if (!full) allLoad= 0; // Склад пуст

}

// Поместить груз в склад

void Put ( )

{

if (((100 - allLoad) < PartLoad) && (evFromWarehouse != 0))

{

// Недостаточно места в складе для выгрузки грузовика

WarehouseEventArgs ^wH= gcnew WarehouseEventArgs

(left, true);

evFromWarehouse (this, wH); // Сгенерировать событие

return;

}

// Выгрузить грузовик и увеличить порциями груз склада

// с помощью потока

partLoad= PartLoad; // Определить выгрузку

// Создать поток выгрузки склада

thr= gcnew Thread (gcnew ThreadStart (this, Change));

thr -> Start ( ); // Стартовать поток

thr -> Join ( ); // Подождать завершения потока

}

// Получить груз из склада

void Get ( )

{

if (((allLoad) < PartLoad) && (evFromWarehouse != 0))

{

// Недостаточно груза в складе для загрузки грузовика

WarehouseEventArgs ^wH= new WarehouseEventArgs

(left, false);

evFromWarehouse (this, wH); // Сгенерировать событие

return;

}

// Загрузить грузовик и уменьшить порциями груз склада

// с помощью потока

partLoad= -PartLoad; // Определить выгрузку

// Создать поток загрузки склада

thr= gcnew Thread (new ThreadStart (this, Change));

thr -> Start ( ); // Стартовать поток

thr -> Join ( ); // Подождать завершения потока

}

protected:

// Поместить или получить груз порциями и с временной задержкой

void Change ( )

{

// Выполнить операцию только с одним грузовиком

Monitor::Enter (this); // Начать критическую секцию

for (int i= 0; i < numParts; i++)

if ((allLoad >= 0 && partLoad < 0) ||

(allLoad <= 100 && partLoad > 0))

{

allLoad += partLoad/numParts;

Thread::Sleep (timePeriod);

Invalidate ( );

}

Monitor::Exit (this); // Завершить критическую секцию

}

// Перерисовать размещение груза в складе

virtual void OnPaint (PaintEventArgs ^e)

{

e -> Graphics -> FillRectangle (new SolidBrush (Color::Yellow),

0, 100 - allLoad, ClientSize.Width, ClientSize.Height);

e -> Graphics -> DrawString (allLoad.ToString ( ), Font,

new System::Drawing::SolidBrush (Color::Blue), 5, 10);

}

};

}

Соседние файлы в папке КОП-Примеры