Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

В классе Thread пространства имен System.Threading определен ряд методов и свойств для управления потоками.

Поиск

Чтобы создать поток, необходимо создать объект типа Thread. В классе Thread определен следующий конструктор:

public Thread (ThreadStart entryPoint)

Здесь:

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

Тип ThreadStart — это делегат, определенный в среде.NET Framework:

Public delegate void ThreadStart ()

Метод, представляющий поток, должен иметь тип возвращаемого значения void и не принимать никаких аргументов.

Пример:

Thread t2 = new Thread (new ThreadStart (Method));

Для запуска потока на выполнение необходимо вызвать метод Start(), который определяется в классе Thread:

Public void Start()

После выхода из entryPolnt-метода выполнение потока автоматически завершается.

 

Пример.

t2.Start();

Метод Sleep() приостановливает выполнение потока, из которого он был вызван, на период времени, заданный в миллисекундах.

Public static void Sleep (int milliseconds)

Пример 1. Создание нового потока на базе статического метода

using System;

using System.Threading;

 

class Class1

{

// Дочерний поток. Метод Coundown считает от 1 до 1000

public static void Method ()

{

for (int i = 1; i <= 10000; i++)

Console.Write (i + " ");

}

 

 

// Стартовый поток

static void Main ()

{

// Создание второго потока

// ThreadStart dlg = new ThreadStart(Method));

// Thread t2 = new Thread (dlg);

 

Thread t2 = new Thread (new ThreadStart (Method));

 

// Запуск потока

t2.Start();

 

// В это же время метод Method вызывается в основном потоке

Method ();

 

Console.ReadLine();

}

}

 

 

Пример 2. Создание нового потока на базе динамического метода

 

using System;

using System.Threading;

 

class Class1

{

public int count;

private string thrdName;

 

public Class1(string name)

{

count = 0;

thrdName = name;

}

 

// Начало (входная точка) потока.

public void Run ()

{

Console.WriteLine (thrdName + " стартовал.");

 

do

{

Console.Write ("#");

 

Thread. Sleep (300);

 

} while (++count < 10);

 

Console.WriteLine ("\n" + thrdName + " завершен.");

}

}

 

class MultiThread

{

public static void Main ()

{

Console.WriteLine ("Основной поток стартовал.");

 

// Сначала создаем объект класса Class1.

Class1 mt = new Class1 ("Дочерний поток");

 

// Затем из метода этого объекта создаем поток.

Thread newThrd = new Thread (new ThreadStart(mt.Run));

 

 

newThrd.Start(); // Запускаем выполнение потока.

 

do

{

Console.Write(".");

 

Thread. Sleep (200);

} while (mt.count!= 10);

 

Console.WriteLine ("Основной поток завершен.");

}

}

 

 

В VS 2005 возможен вызов параметризированного конструктора Thread без делегата. Благодаря такой возможности можно запускать поток, передавая ему параметр в методе Start():

using System;

using System.Threading;

 

Public class Work

{

Public static void Main()

{

// To start a thread using a shared thread procedure, use the class name and

// method name when you create the ParameterizedThreadStart delegate.

 

// C# infers the appropriate delegate creation syntax:

// new ParameterizedThreadStart(Work.DoWork)

 

Thread newThread = new Thread(Work.DoWork);

// Thread newThread = new Thread(new ParameterizedThreadStart(Work.DoWork));

// Use the overload of the Start method that has a parameter of type Object.

// You can create an object that contains several pieces of data, or you can pass

// any reference type or value type.

// The following code passes the integer value 42.

 

newThread.Start(42);

 

// To start a thread using an instance method for the thread

// procedure, use the instance variable and method name when

// you create the ParameterizedThreadStart delegate.

// C# infers the appropriate delegate creation syntax:

// new ParameterizedThreadStart(w.DoMoreWork)

 

Work w = new Work();

newThread = new Thread(w.DoMoreWork);

 

// Pass an object containing data for the thread.

 

newThread.Start ("The answer.");

}

 

 

public static void DoWork (object data)

{

Console.WriteLine("Static thread procedure. Data='{0}'", data);

}

 

 

public void DoMoreWork (object data)

{

Console.WriteLine("Instance thread procedure. Data='{0}'", data);

}

}

 

 

/* This code example produces the following output (the order

of the lines might vary):

 

Static thread procedure. Data='42'

Instance thread procedure. Data='The answer'

*/

 

 

Если метод Start содержит параметр, то и вызываемый метод должен быть определен с параметром типа object.

 

Создание нескольких потоков в конструкторе класса и синхронизация их завершения.

 

В классе Thread определено свойство Name, которое хранит имя потока:

public string Name { get; set; }

 

 

Первый способ синхронизации завершения.

 

В классе Thread свойство IsAlive возвращает значение true, если поток, для которого оно опрашивается, еще выполняется. В противном случае оно возвращает значение false.

 

// Используем свойство IsAlive для установления факта

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

 

using System;

using System.Threading;

 

class Class1

{

public int count; // количество циклов ожидания

public Thread thrd;

private char id; // идентификатор потока

 

public Class1(string name, char idt)

{

count = 0;

id = idt;

 

thrd = new Thread (new ThreadStart (this.Run));

thrd.Name = name; // имя потока

thrd.Start();

}

// Входная точка потока.

Void Run()

{

Console.WriteLine(thrd.Name + " стартовал.");

do

{

Console.Write (id);

Thread.Sleep(300);

}

while (++count < 10);

Console.WriteLine("\n" + thrd.Name + " завершен.");

}

}

 

class MoreThreads

{

public static void Main()

{

Console.WriteLine("Основной поток стартовал.");

 

// Создаем три потока.

Class1 mt1 = new Class1("Дочерний поток 1", '#');

Class1 mt2 = new Class1("Дочерний поток 2", '*');

Class1 mt3 = new Class1("Дочерний поток 3", '-');

 

do

{

Console.Write(".");

Thread.Sleep(200);

} while (mt1.thrd.IsAlive && mt2.thrd.IsAlive && mt3.thrd.IsAlive);

 

Console.WriteLine("\n Основной поток завершен.");

}

}

 

 

Второй способ состоит в вызове метода Join(), который переводит поток, в котором он был вызван, в состояние ожидания завершения объектного потока.

 

 

class MoreThreads

{

public static void Main()

{

Console.WriteLine("Основной поток стартовал.");

 

// Создаем три потока.

MyThread mt1 = new MyThread("Дочерний поток 1", '#');

MyThread mt2 = new MyThread("Дочерний поток 2", '*');

MyThread mt3 = new MyThread("Дочерний поток 3", '-');

 

mt1.thrd. Join ();

Console.WriteLine("\nДочерний поток 1 присоединен.");

 

mt2.thrd. Join ();

Console.WriteLine("Дочерний поток 2 присоединен.");

 

mt3.thrd. Join ();

Console.WriteLine("Дочерний поток 3 присоединен.");

 

Console.WriteLine("\nОсновной поток завершен.");

}

}

 

 

Свойство IsBackground

Среда.NET Framework определяет два типа потоков: высокоприоритетные и фоновые.

Фоновые потоки заканчиваются автоматически после завершения всех высокоприоритетных потоков.

Чтобы перевести поток в категорию фоновых, достаточно присвоить свойству IsBackground значение true. Значение false означает, что соответствующий поток является высоко­приоритетным.

Формат свойства:

public bool IsBackground { get; set; }

Приоритеты потоков

После старта дочерний поток получает стандартное значение приоритета. Его можно изменить с помощью свойства Priority, которое является членом класса Thread.

Общий формат его использования таков:

public ThreadPriority Priority { get; set; }

Здесь ThreadPriority — перечисление, которое определяет следующие пять значений приоритета:

ThreadPriority.Highest

ThreadPriority.AboveNormal

ThreadPriority.Normal

ThreadPriority.BelowNormal

ThreadPriority.Lowest

По умолчанию потоку присваивается значение приори­тета ThreadPriority.Normal.

Рассмотрим на примере, какой поток быстрее увеличит в цикле переменную count до 1 000 000 000.

// Демонстрация использования приоритетов потоков.

 

using System;

using System.Threading;

 

class Class1

{

public int count;

public Thread thrd;

 

static bool stop = false;

static string currentName;

 

// Создаем новый поток.

//Этот конструктор не запускает потоки на выполнение. */

 

public Class1(string name)

{

count = 0;

thrd = new Thread(new ThreadStart(this.Run));

thrd.Name = name;

currentName = name;

}

 

void Run()

{

Console.WriteLine("Поток " + thrd.Name + " стартовал");

do

{

count++;

 

if (currentName!= thrd.Name)

{

currentName = thrd.Name;

Console.WriteLine ("Выполняется поток " + currentName);

}

 

} while (stop == false && count < 1000000000);

stop = true;

 

Console.WriteLine("Поток " + thrd.Name + " завершен");

}

}

class PriorityDemo

{

public static void Main()

{

Class1 mt1 = new Class1("с высоким приоритетом");

Class1 mt2 = new Class1("с низким приоритетом");

 

// Устанавливаем приоритеты.

mt1.thrd.Priority = ThreadPriority.AboveNormal;

mt2.thrd.Priority = ThreadPriority.BelowNormal;

 

// Запускаем потоки на выполнение.

mt1.thrd.Start();

mt2.thrd.Start();

 

mt1.thrd.Join();

mt2.thrd.Join();

 

Console.WriteLine();

Console.WriteLine("Поток " + mt1.thrd.Name + " досчитал до " + mt1.count);

Console.WriteLine("Поток " + mt2.thrd.Name + " досчитал до " + mt2.count);

}

}

 



Поделиться:


Последнее изменение этой страницы: 2016-09-05; просмотров: 250; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 13.59.73.248 (0.008 с.)