русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

ТЕхнология .NET Remoting 3 страница


Дата добавления: 2013-12-23; просмотров: 748; Нарушение авторских прав


Для иллюстрации использования интерфейса ISerializable предположим, что у нас определен класс с двумя текстовыми полями. Далее, пусть требуется сохранять эти поля в верхнем регистре, а считывать в нижнем регистре. Вот код, который выполняет требуемую сериализацию (не забудьте подключить пространство имен System.Runtime.Serialization):

[Serializable]

class MyStringData : ISerializable {

public string dataItemOne, dataItemTwo;

public MyStringData(){}

private MyStringData(SerializationInfo si,

StreamingContext ctx) {

// Получаем значения из потока и преобразовываем их

dataItemOne = si.GetString("First_Item").ToLower();

dataItemTwo = si.GetString("dataItemTwo").ToLower();

}

 

void ISerializable.GetObjectData(SerializationInfo info,

StreamingContext ctx) {

// Заполняем объект SerializationInfo

info.AddValue("First_Item", dataItemOne.ToUpper());

info.AddValue("dataItemTwo", dataItemTwo.ToUpper());

}

}

Как видим, в конструкторе типа сериализованные значения извлекаются при помощи метода GetString(). В классе SerializationInfo существуют аналогичные методы для других типов данных.

Во второй версии .NET Framework для поддержки собственных форматов сериализации существует ряд атрибутов: [OnSerializing], [OnSerialized], [OnDeserializing], [OnDeserialized]. Этими атрибутами помечаются методы класса. Механизм сериализации будет автоматически вызвать помеченный метод в требуемый момент. Метод, который помечается одним из вышеуказанных атрибутов, должен принимать в качестве параметра объект класса StreamingContext и не возвращать значений.

Для иллюстрации пользовательской сериализации с применением атрибутов рассмотрим класс MoreData, который при сериализации ведет себя аналогично классу MyStringData.

[Serializable]

class MoreData {



public string dataItemOne, dataItemTwo;

// Если метод помечен атрибутом [OnSerializing], то он

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

[OnSerializing]

internal void OnSerializing(StreamingContext context) {

dataItemOne = dataItemOne.ToUpper();

dataItemTwo = dataItemTwo.ToUpper();

}

 

// Если метод помечен атрибутом [OnDeserialized], то он

// вызывается после чтения данных из потока

[OnDeserialized]

internal void OnDeserialized(StreamingContext context) {

dataItemOne = dataItemOne.ToLower();

dataItemTwo = dataItemTwo.ToLower();

}

}

2.8. ВВЕДЕНИЕ В XML

XML – это способ записи структурированных данных. Под «структурированными данными» обычно подразумевают такие объекты, как электронные таблицы, адресные книги, конфигурационные параметры. XML-данные содержатся в документе, в роли которого может выступать файл, поток или другое хранилище информации, способное поддерживать текстовый формат.

Любой XML-документ строится по определенным правилам. XML-данные состоят из набора элементов. Каждый элемент определяется при помощи имени и открывающего и закрывающего тэга. Открывающий тэг элемента записывается в форме <имя_элемента>, закрывающий тэг – в форме </имя_элемента>. Между открывающим и закрывающим тэгами размещается содержимое элемента. Приведем пример простейшего элемента:

<name>This is a text</name>

Элемент может содержать вложенные элементы с другими именами, но в XML-документе всегда должен быть единственный элемент, называемый корневым, никакая часть которого не входит в содержимое любого другого элемента.

<Group>

<student>

<name>

Ivanov

</name>

</student>

<student>

<name>

Petrov

</name>

<ball>

4.0

</ball>

</student>

</Group>

В приведенном примере XML-документ содержит корневой элемент с именем Group, который, в свою очередь, содержит два элемента с именем student. Обратите внимание на разное количество вложенных элементов у первого и второго «студентов» (это допустимо).

Имена тегов элементов чувствительны к регистру! Элементы, задаваемые открывающим и закрывающим тегами, должны быть правильно вложены друг в друга. Следующий пример не является правильным:

<text>

<bold><italic>XML</bold></italic>

</text>

Элемент без содержимого может быть записан в специальной форме: <name/>.

Имена элементов могут содержать буквы, цифры, дефисы (-), символы подчеркивания (_), двоеточия (:) и точки (.), однако начинаться они могут только с буквы или символа подчеркивания. Двоеточие может быть использовано только в специальных случаях, когда оно разделяет так называемое пространство имен. Имена элементов, начинающиеся с xml, вне зависимости от комбинации регистров букв в этом выражении зарезервированы для нужд стандарта.

Элемент может иметь ни одного, один или несколько атрибутов. Правила на имена атрибутов накладываются такие же, как и на имена элементов. Имена атрибутов отделяются от их значений знаком =. Значение атрибута заключается в апострофы или в двойные кавычки. Если апостроф или двойные кавычки присутствуют в значении атрибута, то используются те из них, которые не встречаются в этом значении. Приведем пример элементов с атрибутами:

<elements-with-attributes>

<el _ok = "yes"/>

<one attr = "a value"/>

<several first = "1" second = "2" third = "333"/>

<apos_quote case1 = "John's"

case2 = 'He said: "Hello, world!" '/>

</elements-with-attributes>

Символы < и & не могут быть использованы в тексте, так как они используются в разметке XML-документа. Если эти символы необходимы, следует использовать &lt; вместо < и &amp; вместо &. Символы >, ", и ' также могут быть заменены &gt;, &quot; и &apos;, соответственно.

XML-документ может содержать комментарии, записываемые в обрамлении <!-- и -->. В тексте комментариев не должна содержаться последовательность из двух знаков дефиса:

<!-- Group 252001 list -->

<Group>

<student>

<name>

Ivanov

</name>

</student>

</Group>

Документ может содержать инструкции по обработке (PI), несущие информацию для приложений. Инструкции по обработке записываются в обрамлении <? и ?>.

<example>

<?perl lower-to-upper-case ?>

<?web-server add-header = "university" ?>

<text>Some text</text>

</example>

Секция CDATA используется для того, чтобы обозначить части документа, которые не должны восприниматься как разметка. Секция CDATA начинается со строки <![CDATA[ и заканчивается строкой ]]>. Внутри самой секции не должна присутствовать строка ]]>.

<example>

<![CDATA[ <aaa>bb&cc<<<]]>

</example>

XML-документ может, но не обязан начинаться с XML-декларации, определяющей используемую версию XML:

<?xml version="1.0"?>

Декларация может содержать необязательный атрибут, указывающий кодировку XML-документа:

<?xml version="1.0" encoding="UTF-16"?>

Если XML-документ оформлен по описанным выше правилам, то он называется хорошо оформленным XML-документом. Если хорошо оформленный документ удовлетворяет некой схеме, задающей структуру и содержание, то документ называется правильно оформленным. Существует несколько способов для описания приемлемых схем документов. Один из способов – использование блоков определения типа документа (document type definitions, DTD). Современным способом считается использование языка XML Schema Definitions (XSD), который сам основан на XML.

Описание XSD может потребовать нескольких лекций, поэтому просто приведем пример файла students.xsd на этом языке:

<?xml version="1.0" encoding="UTF-8"?>

<xs:schema xmlns:xs=http://www.w3.org/2001/XMLSchema

elementFormDefault="qualified"

attributeFormDefault="unqualified">

<xs:element name="Students">

<xs:complexType>

<xs:choice maxOccurs="unbounded">

<xs:element name="student">

<xs:complexType>

<xs:sequence>

<xs:element name="name" type="xs:string"/>

<xs:element name="year" type="xs:gYear"/>

<xs:element name="ball" type="xs:double"

minOccurs="0"/>

</xs:sequence>

<xs:attribute name="Department" type="xs:string"

use="optional"/>

</xs:complexType>

</xs:element>

</xs:choice>

</xs:complexType>

</xs:element>

<xs:attribute name="Department"/>

</xs:schema>

Данная схема описывает правильные документы, которые должны содержать корневой элемент Students, элемент Students должен содержать один или несколько элементов student, а элемент student должен содержать один элемент name, один элемент year и может содержать элемент ball. Также определен порядок и тип элементов, и наличие необязательного атрибута Department у элемента student.

Существует большое количество разнообразного программного обеспечения для работы с XML-схемами, в частности, для создания схем и проверки соответствия XML-документа некоторой схеме. Упомянем такие программы как XMLSPY и утилиту Xsd.exe, которая входит в состав .NET SDK.

2.9. РАБОТА С XML-документами В .NET FRAMEWORK

Рассмотрим вопросы, связанные с чтением и записью XML-документов. Для этих целей предназначен набор классов из пространства имен System.Xml. Упомянем такие классы, как XmlDocument, XmlTextReader, XmlTextWriter, XmlValidatingReader.

Класс XmlReader – это абстрактный класс, предназначенный для чтения xml-данных из потока. В .NET Framework существуют три класса, построенных на основе XmlReader: XmlTextReader (разбор xml-данных на основе текстового потока), XmlNodeReader (разбор XML из набора объектов XmlNode) и XmlValidatingReader (при чтении производится проверка документа с использованием DTD и/или Shema).

Обычно для простого чтения XML достаточно класса XmlTextReader. Конструктор класса может быть вызван в различных формах. В следующем примере предполагается читать данные из файла Students.xml:

XmlTextReader tr = new XmlTextReader("Students.xml");

Объект класса XmlTextReader может быть построен на основе потоков:

XmlTextReader tr = new XmlTextReader(

new TextReader(

new FileStream("Students.xml",

FileMode.Open)));

Как видим, XmlTextReader может извлекать данные из любых потоков, включая сетевые потоки и потоки, связанные с базами данных. XML-данные можно извлекать и из потоков, сконструированных на основе строк:

string xmlContent =

"<book>" +

" <title>Чук и Гек</title>" +

" <author>Аркадий Гайдар</author>" +

"</book>";

XmlTextReader tr = new XmlTextReader(

new StringReader(xmlContent));

После создания объект XmlTextReader извлекает xml-конструкции из потока при помощи метода Read(). Тип текущей конструкции (элемент, атрибут) можно узнать, используя свойство NodeType, значениями которого являются элементы перечисления XmlNodeType. С конструкцией можно работать, используя различные свойства, такие как Name (возвращает имя элемента или атрибута), Value (возвращает данные элемента) и так далее.

В таблице 16 приведены все возможные значения перечисления XmlNodeType.

Таблица 16

Значения перечисления XmlNodeType

Значение Пример
Attribute Department="Informatics"
CDATA <![CDATA["This is character data"]]>
Comment <!-- This is a comment -->
Document <Students>
DocumentType <!DOCTYPE Students SYSTEM " Students.dtd">
Element <student>
EndElement </student>
Entity <!ENTITY filename "Strats.xml">
EntityReference &lt;
Notation <!NOTATION GIF89a SYSTEM "gif">
ProcessingInstruction <?perl lower-to-upper-case ?>
Text Petrov
Whitespace <Make/>\r\n<Model/>
XmlDeclaration <?xml version="1.0"?>

Дадим некоторые комментарии. Значения DocumentType, Entity, EntityReference и Notation связаны с блоком определения типа документа (document type definition, DTD). Напомним, что при помощи подобного блока, который может являться частью XML-документа, задается приемлемая схема документа. Значение Whitespace представляет пустое (вернее, не обрабатываемое) пространство между тэгами.

Следующий пример демонстрирует разбор xml-файла и вывод разобранных конструкций на экран:

using System;

using System.Xml;

 

class XmlFun {

static void Main() {

XmlTextReader rdr = new XmlTextReader("Students.xml");

// Разбираем файл и выводим на консоль каждый элемент

while(rdr.Read()) {

// Реагируем в зависимости от NodeType

// Не все значения NodeType отслеживаются!!!

switch(rdr.NodeType) {

case XmlNodeType.Element:

Console.Write("<{0}>", rdr.Name);

break;

case XmlNodeType.Text:

Console.Write(rdr.Value);

break;

case XmlNodeType.CDATA:

Console.Write("<![CDATA[{0}]]>", rdr.Value);

break;

case XmlNodeType.Comment:

Console.Write("<!--{0}-->", rdr.Value);

break;

case XmlNodeType.XmlDeclaration:

Console.Write("<?xml version='1.0'?>");

break;

case XmlNodeType.EndElement:

Console.Write("</{0}>", rdr.Name);

break;

}

}

}

}

Набор методов класса XmlTextReader вида MoveXXX(), таких как MoveToNextElement(), может использоваться для извлечения соответствующей конструкции из потока. Методы используются для перехода к следующей конструкции, вернуться к просмотренным конструкциям нельзя.

Подобно тому, как класс XmlReader является абстрактным классом для чтения xml-данных из потока, класс XmlWriter – это абстрактный класс для создания xml-данных. Подчеркнем, что xml-данные всегда могут быть созданы при помощи простой строки и затем записаны в любой поток:

string xmlContent = "<greeting>" + message + "</greeting>";

Однако такой подход не лишен недостатков: возрастает вероятность неправильного формирования структуры XML-документа из-за элементарных ошибок программиста. Класс XmlWriter предоставляет более «помехоустойчивый» способ генерации XML-документа. В следующем примере создается документ, содержание которого соответствует xmlContent:

using System;

using System.Xml;

 

class XmlFun {

static void Main() {

string message = "Hello, dude!";

XmlTextWriter xw = new XmlTextWriter("greetings.xml",

System.Text.Encoding.UTF8);

xw.Formatting = Formatting.Indented;

xw.Indentation = 2;

xw.WriteStartDocument();

xw.WriteStartElement("greeting");

xw.WriteString(message);

xw.WriteEndElement();

xw.WriteEndDocument();

xw.Flush();

}

}

Класс XmlDocument представляет XML-документ в виде дерева узлов-элементов. Каждый узел является экземпляром класса XmlNode, который содержит методы и свойства для навигации по дереву, чтения и записи информации узла и другие.

Пусть имеется следующий файл Students.xml:

<?xml version="1.0" encoding="UTF-8"?>

<Students>

<student Department="Informatics">

<name>Ivanov</name>

<year>1980</year>

</student>

<student>

<name>Petrov</name>

<year>1980</year>

<ball>5.0</ball>

</student>

<student Department="Informatics">

<name>Sidorova</name>

<year>1981</year>

<ball>4.5</ball>

</student>

</Students>

Следующий код создает объект класса XmlDocument, и этот объект загружается информацией из файла Students.xml:

XmlDocument doc = new XmlDocument();

doc.Load("Students.xml");

Метод Load() считывает документ и разбирает его в памяти на элементы. Если документ не является правильно форматированным, генерируется исключение XmlException.

За успешным вызовом метода Load() обычно следует обращение к свойству DocumentElement объекта, представляющего документ. Данное свойство возвращает ссылку на объект класса XmlNode. Этот объект позволяет обнаружить у элемента дочерние элементы (свойство HasChildNodes) и получить к ним доступ, используя свойство ChildNodes, являющееся коллекцией типа XmlNodeList. Комбинация свойств HasChildNodes и ChildNodes позволяет использовать при обработке XML-документов рекурсивный подход:

using System;

using System.Xml;

 

class MainClass {

public static void Main() {

XmlDocument doc = new XmlDocument();

doc.Load("Students.xml");

OutputNode(doc.DocumentElement);

}

 

public static void OutputNode(XmlNode node) {

Console.WriteLine("Type={0} \t Name={1} \t Value={2}",

node.NodeType, node.Name, node.Value);

// Если есть дочерние элементы,

// рекурсивно обрабатываем их

if(node.HasChildNodes) {

XmlNodeList children = node.ChildNodes;

foreach(XmlNode child in children)

OutputNode(child);

}

}

}

Приведенный код не выводит значения атрибутов элемента. Свойство ChildNodes не включает атрибуты. Все атрибуты элемента хранятся в свойстве Attributes и представлены типом XmlAttribute. Следующий фрагмент кода позволяет обработать атрибуты элемента:

void OutputNode(XmlNode node) { . . . if(node.Attributes != null){ foreach (XmlAttribute attr in node.Attributes) Console.WriteLine("Type={0}\tName={1}\tValue={2}", attr.NodeType, attr.Name, attr.Value); } . . .}

У объекта класса XmlNode имеются свойства NodeType, Name и Value. Следует иметь в виду, что обращаться к Name и Value нужно в зависимости от значения NodeType. У элементов (XmlNodeType.Element) нет Value, но определено Name. У текста (XmlNodeType.Text) определено Name, но нет Value. У атрибутов определены и Name и Value.

Для того чтобы получить определенный узел или набор узлов, нет необходимости итеративно просматривать весь XML-документ. Для этих целей можно использовать методы класса XmlDocument такие как GetElementsByTagName(), SelectNodes(), SelectSingleNode().

При помощи класса XmlDocument можно не только читать, но и создавать XML-документы. В следующем примере загружается файл Students.xml, удаляется его первый элемент (первый студент), добавляется еще один элемент, описывающий студента, и результат сохраняется в файл Students_new.xml.

using System;

using System.Xml;

class XmlWork {

static void Main() {

XmlDocument doc = new XmlDocument();

// Загружаем информацию из файла

doc.Load("Students.xml");

 

// Создаем необходимые элементы

XmlNode student = doc.CreateElement("student");

XmlNode name = doc.CreateElement("name");

XmlNode year = doc.CreateElement("year");

XmlNode ball = doc.CreateElement("ball");

 

// Создаем текстовое наполнение элементов

XmlNode text1 = doc.CreateTextNode("Mr. Zorg");

XmlNode text2 = doc.CreateTextNode("1990");

XmlNode text3 = doc.CreateTextNode("4.7");

 

// Связываем элементы и текстовое наполнение

name.AppendChild(text1);

year.AppendChild(text2);

ball.AppendChild(text3);

 

// Связываем элементы в одну структуру

student.AppendChild(name);

student.AppendChild(year);

student.AppendChild(ball);

 

// Получаем корневой элемент документа

XmlNode root = doc.DocumentElement;

 

// Удаляем первый дочерний элемент

root.RemoveChild(root.FirstChild);

 

// Добавляем сконструированный нами элемент

root.AppendChild(student);

 

// Сохраняем все в файл

doc.Save("Students_new.xml");

}

}

Другие методы класса XmlDocument, которые могут быть полезны при модификации XML-документа, это методы PrependChild(), InsertBefore(), InsertAfter(), RemoveAll(), ReplaceChild(). Для конструирования элемента можно использовать свойство XmlNode.InnerText, которое должно содержать подходящую строку, представляющую содержимое элемента:

XmlNode student = doc.CreateElement("student");

student.InnerText = "<name>Mr. Zorg</name>" +

"<year>1990</year>" +

"<ball>4.7</ball>";

2.10. МНогопоточное программирование

Классы, предназначенные для поддержки многопоточного программирования, сосредоточены в пространстве имен System.Threading. В среде .NET каждый поток представлен объектом класса System.Threading.Thread. Для организации собственного потока необходимо создать объект указанного класса. Класс Thread имеет единственный конструктор:

public Thread(ThreadStart start);

В качестве параметра конструктор принимает делегат типа ThreadStart, который должен ссылаться на пользовательский метод, выполняемый в потоке.

public delegate void ThreadStart();

Следует учесть, что создание потока не подразумевает его автоматического запуска. Для запуска потока требуется вызвать у объекта метод Start().

Продемонстрируем создание и запуск потоков на простейшем примере. Программа содержит два потока, каждый из которых в бесконечном цикле выводит данные на консоль:

using System;

using System.Threading; //Необходимо для работы с потоками

 

class MainClass {

// Эта функция будет выполняться в отдельном потоке

public static void DoSomeWork() {

while (true) {

Console.WriteLine("The second thread");

// Создаем видимость работы

for (int i = 0; i < 1000000; i++){ i++; }

}

}

 

public static void Main() {

// Создали объект потока

Thread th = new Thread(new ThreadStart(DoSomeWork));

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

th.Start();

// Создаем видимость работы

while (true) {

Console.WriteLine("The first thread");

for (int i = 0; i < 1000000; i++){ i++; }

}

}

}

Рассмотрим работу с членами класса Thread подробнее. Любой поток характеризуется приоритетом выполнения, который влияет на количество квантов процессорного времени, выделяемых потоку. Для работы с приоритетами класс Thread содержит свойство Priority, доступное для чтения и записи. Значением свойства являются элементы перечисления ThreadPriority: Lowest, BelowNormal, Normal, AboveNormal, Highest:

// Создали объект потока

Thread th = new Thread(new ThreadStart(DoSomeWork));

// Назначим потоку низкий приоритет

th.Priority = ThreadPriority.Lowest;

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

th.Start();

Среда исполнения платформы .NET разделяет все потоки на фоновые и основные. Главное приложение не может завершиться, пока не завершены все его основные потоки. Если работа приложения завершается, а некоторые фоновые потоки еще работают, то их работа автоматически прекращается. Таким образом, к основным следует относить такие потоки, которые выполняют критические для приложения действия. Для установки типа потока следует использовать свойство IsBackground булевого типа. Следующий пример показывает применение свойства:

using System;

using System.Threading;

 

class MainClass {

public static void DoSomeWork() {

while (true) {

Console.WriteLine("The second thread");

// Этот метод приостанавливает поток на 400 мсек

Thread.Sleep(400);

}

}

 

public static void Main() {

Thread th = new Thread(new ThreadStart(DoSomeWork));

th.IsBackground = true; // Поток будет фоновым

th.Start();

// "Усыпили" основной поток на 2 секунды

Thread.Sleep(2000);

Console.WriteLine("Quit from main thread");

}

}

По умолчанию любой поток создается как основной, поэтому, если закомментировать строку th.IsBackground = true и запустить приложение, то самостоятельно закончить работу оно не сможет.

Класс Thread предоставляет встроенные механизмы управления потоками. Метод Suspend() вызывает приостановку потока, метод Resume() возобновляет работу потока. Статический метод Sleep() приостанавливает выполнение того потока, в котором вызывается, на указанное количество миллисекунд:

// Пусть объект th связан с некоторым потоком

th.Suspend(); // Приостановили поток

th.Resume(); // Запустили снова

Thread.Sleep(2000); // "Усыпили" поток на 2 секунды

Для приостановки работы произвольного потока на заданное время может использоваться такой код (штатных методов для этого не существует):

th.Suspend();

Thread.Sleep(2000);

th.Resume();

Если вызвать метод Sleep() с параметром -1, то поток будет остановлен навсегда.

Метод Join() позволяет дождаться завершения работы того потока, у которого вызывается. Модификация данного метода блокирует выполнение текущего потока на указанное количество миллисекунд:

Thread th = new Thread(new ThreadStart(DoSomeWork));

th.Start(); // Создали и запустили поток

th.Join(); // Ждем, пока этот поток отработает

. . .

Thread th = new Thread(new ThreadStart(DoSomeWork));

th.Start(); // Создали и запустили поток

 

// Будем ждать 1 секунду. Если за это время поток th

// завершиться, то значение res будет true

bool res = th.Join(1000);

Для завершения работы выбранного потока используется метод Abort(). Данный метод генерирует специальное исключение ThreadAbortException. Особенность этого исключения состоит в том, что его невозможно подавить при помощи catch-блока. Исключение может быть отслежено (в частности, тем потоком, который кто-то собирается уничтожить), а при помощи статического метода ResetAbort() запрос на уничтожение потока можно отклонить.

using System;

using System.Threading;

 

class MainClass {

public static void ThreadProc() {

while(true)

try {

Console.WriteLine("Some work...");

Thread.Sleep(1000);

} catch (ThreadAbortException e) {

// Отлавливаем попытку уничтожения и отменяем ее

Console.WriteLine("Somebody tries to kill me!");

Thread.ResetAbort();

}

}

 

public static void Main() {

// Создаем и запускаем поток

Thread th = new Thread(new ThreadStart(ThreadProc));

th.Start();

// Подождем 10 секунд

Thread.Sleep(10000);

// Пытаемся прервать работу потока

th.Abort();

// Дождемся завершения потока. Вернее, никогда мы его

// не дождемся, так как поток сам себя "воскресил"

th.Join();

}

}

Информацию о текущем состоянии потока можно получить посредством свойства ThreadState, значением которого являются элементы перечисления ThreadState. Свойство IsAlive позволяет определить, исполняется ли в данный момент поток. Статическое свойство CurrentThread возвращает объект, представляющий текущий поток. Свойство Name служит для установки или чтения строки с именем потока.



<== предыдущая лекция | следующая лекция ==>
ТЕхнология .NET Remoting 2 страница | ТЕхнология .NET Remoting 4 страница


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Полезен материал? Поделись:

Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.023 сек.