Прошел курс. Получил код 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 . Выполнение кода одной функции в дополнительном потоке
Результат показывает, что в одном домене выполняются два разных потока.