Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка для КР по ООП.doc
Скачиваний:
8
Добавлен:
18.04.2019
Размер:
2.47 Mб
Скачать

2. Посредством общедоступных (public) свойств

Следующий вариант организации взаимодействия между потоками основан на использовании общедоступных свойств. От предыдущего примера отличается тем, что доступ к закрытому счётчику lVal в соответствии с принципами инкапсуляции осуществляется через свойство с блоками get (акцессор) и set (мутатор).

using System;

using System.Threading;

namespace CommunicatingThreadsData

{

public delegate void CallBackFromStartClass (long param);

// Данные. Предмет и основа взаимодействия двух потоков.

class CommonData

{

private long lVal;

public long lValProp

{

get

{

return lVal;

}

set

{

lVal = value;

}

}

public CommonData(long key)

{

lVal = key;

}

}

// Классы Worker и Inspector: основа взаимодействующих потоков.

class Worker

{

CommonData cd;

// Конструктор умолчания...

public Worker(ref CommonData rCDKey)

{

cd = rCDKey;

}

public void startWorker()

{

DoIt(ref cd);

}

// Тело рабочей функции...

public void DoIt(ref CommonData cData)

{//====================================

for (;;)

{

cData.lValProp++;

Console.Write(“{0,25}\r”,cData.lValProp);

}

}//====================================

}

class Inspector

{

long stopVal;

CommonData cd;

CallBackFromStartClass callBack;

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

public Inspector(ref CommonData rCDKey, long key, CallBackFromStartClass cbKey)

{

stopVal = key;

cd = rCDKey;

callBack = cbKey;

}

public void startInspector()

{

measureIt(ref cd);

}

// Тело рабочей функции...

public void measureIt(ref CommonData cData)

{//====================================

for (;;)

{

if (cData.lValProp < stopVal)

{

Thread.Sleep(100);

Console.WriteLine(“\n{0,-25}”,cData.lValProp);

}

else

callBack(cData.lValProp);

}

}//====================================

}

class StartClass

{

static Thread th0, th1;

static CommonData cd;

static long result = 0;

static void Main(string[] args)

{

StartClass.cd = new CommonData(0);

// Конструкторы классов Worker и Inspector несут дополнительную нагрузку.

// Они обеспечивают необходимыми значениями методы,

// выполняемые во вторичных потоках.

Worker work;

// До начала выполнения потока вся необходимая информация доступна методу.

work = new Worker(ref cd);

Inspector insp;

// На инспектора возложена дополнительная обязанность вызова функции-терминатора.

// Для этого используется специально определяемый и настраиваемый делегат.

insp = new Inspector(ref cd, 50000, new CallBackFromStartClass(StartClass.StopMain));

// Стартовые функции потоков должны соответствовать сигнатуре

// класса делегата ThreadStart. Поэтому они не имеют параметров.

ThreadStart t0, t1;

t0 = new ThreadStart(work.startWorker);

t1 = new ThreadStart(insp.startInspector);

// Созданы вторичные потоки.

StartClass.th0 = new Thread(t0);

StartClass.th1 = new Thread(t1);

// Запущены вторичные потоки.

StartClass.th0.Start();

StartClass.th1.Start();

// Ещё раз о методе Join(): Выполнение главного потока приостановлено.

StartClass.th0.Join();

StartClass.th1.Join();

// Потому последнее слово остаётся за главным потоком приложения.

Console.WriteLine(“Main(): All stoped at {0}. Bye.», result);

}

// Функция-член класса StartClass выполняется во ВТОРИЧНОМ потоке!

public static void StopMain(long key)

{

Console.WriteLine(“StopMain: All stoped at {0}...”, key);

// Остановка рабочих потоков. Её выполняет функция-член

// класса StartClass. Этой функции в силу своего определения

// известно ВСЁ о вторичных потоках. Но выполняется она

// в ЧУЖОМ (вторичном) потоке. Поэтому:

// 1. надо предпринять особые дополнительные усилия для того чтобы

// результат работы потоков оказался доступен в главном потоке.

/*StartClass.*/result = key;

// 2. очень важна последовательность остановки потоков,

StartClass.th0.Abort();

StartClass.th1.Abort();

// Этот оператор не выполняется! Поток, в котором выполняется

// метод-член класса StartClass StopMain() остановлен.

Console.WriteLine(“StopMain(): bye.”);

}

}

}