|
Прошел курс. Получил код Dreamspark. Ввожу код на сайте, пишет: Срок действия этого кода проверки уже истек. Проверьте, правильно ли введен код. У вас осталось две попытки. Вы также можете выбрать другой способ проверки или предоставить соответствующие документы, подтверждающие ваш академический статус.
Как активировать код? |
Процессы, домены, потоки в C#
Потоки
Процесс, и домены внутри процесса, создают для исполняемого приложения комфортную среду обитания. Они изолируют код и данные от других исполняемых программ и предоставляют им необходимые сервисы. Но Windows является многозадачной операционной системой и должна выполнять все загруженные в нее задачи. Поэтому, имея в наличии только один процессор, она вынуждена эмулировать многозадачность выделением каждой задаче небольшого кванта времени, создавая иллюзию их одновременного выполнения. Такое поведение вполне приемлемо, потому что многие процессы представляют диалоговые приложения и в большинстве случаев находятся в состоянии простоя, ожидая ( idle ) действий пользователя.
Не все части процесса, ожидающего действий пользователя, могут простаивать одновременно. Некоторые части исполняемого приложения должны продолжать взаимодействовать с пользователем, ожидая его указаний, а другие в это время - исполнять уже полученные указания. Для реализации такого подхода код процесса разбивают на несколько завершенных частей, способных выполняться самостоятельно, и эти части называются потоками ( thread ). Таким образом, поток, это часть кода процесса, который способен реально выполняться процессором в данный момент.
Поток есть ничто иное, как контейнер для контролируемого исполнения какой-то функции. Когда функции выполняются только в одном потоке, работой каждой из них можно управлять только изнутри. Другое дело, когда функция выполняется в отдельном потоке-контейнере. В этом случае работой функции мы можем управлять из создавшего поток внешнего кода. Например, мы можем приостановить выполнение функции, назначить ей приоритет по отношению к функциям других потоков, перевести в фоновый режим работы или вообще прервать ее выполнение.
Процесс по отношению к потокам является контейнером, предоставляет им закрытое адресное пространство и следит за соблюдением политики операционной системы. Но реальный код приложения исполняют потоки. Все они имеют доступ к общей памяти приложения, выделенной им процессом. Но каждый из потоков имеет еще и свою локальную память TLS ( Thread Local Storage ), к которой имеет доступ только он сам.
Различают управляемые и неуправляемые потоки. Управляемые потоки создаются и действуют под контролем среды CRL, а неуправляемые - под контролем самой операционной системы. Любой поток, управляемый или неуправляемый, представлен экземпляром класса System.Threading.Thread.Оперируя сервисами этого класса мы можем контролировать работу потоков. Ниже приведены некоторые из этих сервисов.
Помещение в поток одной функции
Для любого приложения, запущенного на исполнение и загруженного в процесс, автоматически создается хотя бы один поток, который называется основным. Далее сама программа может создавать для отдельных своих частей дополнительные потоки и управлять ими. Этими частями являются методы, содержащие исполнимый код. Рассмотрим создание дополнительного потока и помещения в него одной функции на примере.
using System;
using System.Threading;
namespace Test
{
class MyClass
{
// Закрытые поля с маркерами потоков
int markerBaseThread, markerNewThread;
// Открытые поля с идентификаторами доменов
public int domainBaseThread, domainNewThread;
// Свойства доступа закрытых полей (только для чтения)
public int MarkerBaseThread
{
get { return markerBaseThread; }
}
public int MarkerNewThread
{
get { return markerNewThread; }
}
// Конструктор исполняется в основном потоке
public MyClass()
{
// Извлечем маркер текущего потока
markerBaseThread = Thread.CurrentThread.GetHashCode();
// Извлекаем идентификатор домена
domainBaseThread = Thread.GetDomainID();
// Создаем специальный делегат со ссылкой на функцию
// Создаем новый поток и присоединяем к нему исполняемый код
// Запускаем код функции в новом потоке из текущего потока
ThreadStart del = new ThreadStart(Func); // Объект-делегат
Thread th = new Thread(del); // Новый поток
th.Start(); // Выполнить функцию
}
// Метод будет исполняться в дополнительном потоке
private void Func()
{
// Извлекаем маркер текущего потока
markerNewThread = Thread.CurrentThread.GetHashCode();
// Извлекаем идентификатор домена
domainNewThread = Thread.GetDomainID();
}
}
// Класс с точкой входа
class Program
{
// Исполняется в основном потоке
static void Main()
{
// Настройка консоли
Console.Title = "Выполнение кода в
дополнительном потоке";
Console.ForegroundColor = ConsoleColor.White;
Console.CursorVisible = false;
Console.WindowWidth = 57;
Console.WindowHeight = 4;
MyClass obj = new MyClass();// Исполняем
// Показываем маркеры
Console.WriteLine("Поток выполнения
конструктора MyClass(): {0} (в домене {1})",
obj.MarkerBaseThread, obj.domainBaseThread);
Console.WriteLine("Поток выполнения метода
Func(): {0} (в домене {1})",
obj.MarkerNewThread, obj.domainNewThread);
Console.WriteLine("Поток выполнения метода
Main(): {0} (в домене {1})",
Thread.CurrentThread.GetHashCode(), Thread.GetDomainID());
Console.ReadLine(); // Ждем нажатия клавиши Enter
}
}
}
Листинг
11.4 .
Выполнение кода одной функции в дополнительном потоке
Результат показывает, что в одном домене выполняются два разных потока.
