
Приложение 1. Программа LorryAndWarehouse без удалённого объекта на языке C#
Библиотека csWarehouse.Dll
///////////////
// C# File csWarehouse.dll компонент Warehouse
using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using System.ComponentModel;
namespace csWarehouseDll
{
// Класс данных события evFromWarehouse
public class WarehouseEventArgs: EventArgs
{
private bool left; // Признак идентификации склада
private bool full; // Признак заполненности склада
public WarehouseEventArgs (bool left, bool full)
{
this.left= left; this.full= full;
}
// Свойство заполнения склада
public bool Full
{
get {return full;}
}
// Свойство идентификации склада
public bool Left
{
get {return left;}
}
}
// Делегат события о переполнении и опустошении склада
public delegate void DelEvFromWarehouse (object sender,
WarehouseEventArgs args);
// Интерфейс склада
public interface IWarehouse
{
void Put ( ); // Поместить груз в склад
void Get ( ); // Получить груз из склада
event DelEvFromWarehouse evFromWarehouse; // Ссылка на объект
// события о переполнении и опустошении склада
}
// Компонент склада
public class Warehouse: UserControl, IWarehouse
{
bool left; // Признак идентификации склада
int allLoad= 100; // Текущий размер груза в складе
int PartLoad= 10; // Размер груза грузовика
int partLoad; // Получаемая или помещаемая порция груза
int numParts= 5; // Количество порций
int timePeriod= 100; // Время получения или помещения
// порции груза
Thread thr; // Ссылка на объект потока
public event DelEvFromWarehouse evFromWarehouse; // Ссылка
// на объект события о переполнении и опустошении склада
// Конструктор
public Warehouse (bool left, bool full)
{
this.left= left;
if (!full) allLoad= 0; // Склад пуст
}
// Поместить груз в склад
public void Put ( )
{
if (((100 - allLoad) < PartLoad) && (evFromWarehouse != null))
{
// Недостаточно места в складе для выгрузки грузовика
WarehouseEventArgs wH= new WarehouseEventArgs (left,
true);
evFromWarehouse (this, wH); // Сгенерировать событие
return;
}
// Выгрузить грузовик и увеличить порциями груз склада
// с помощью потока
partLoad= PartLoad; // Определить выгрузку
// Создать поток выгрузки склада
thr= new Thread (new ThreadStart (Change));
thr.Start ( ); // Стартовать поток
thr.Join ( ); // Подождать завершения потока
}
// Получить груз из склада
public void Get ( )
{
if (((allLoad) < PartLoad) && (evFromWarehouse != null))
{
// Недостаточно груза в складе для загрузки грузовика
WarehouseEventArgs wH= new WarehouseEventArgs
(left, false);
evFromWarehouse (this, wH); // Сгенерировать событие
return;
}
// Загрузить грузовик и уменьшить порциями груз склада
// с помощью потока
partLoad= -PartLoad; // Определить выгрузку
// Создать поток загрузки склада
thr= new Thread (new ThreadStart (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); // Завершить критическую секцию
}
// Перерисовать размещение груза в складе
protected override void OnPaint (PaintEventArgs e)
{
base.OnPaint (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);
}
}
}