русс | укр

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

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

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

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


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

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


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


Следующий вопрос, рассматриваемый в данном параграфе, это взаимодействие сборок. Как правило, большие проекты состоят из нескольких сборок, ссылающихся друг на друга. Среди этих сборок имеется некая основная (обычно оформленная как исполняемый файл *.exe), а другие сборки играют роль подключаемых библиотек с кодом необходимых классов (обычно такие сборки – это файлы с расширением *.dll). Платформа .NET разделяет сборки на локальные (или сборки со слабыми именами) и глобальные (или сборки с сильными именами).

Представим пример, который будем использовать в дальнейшем. Пусть имеется следующий класс (в файле UL.cs), содержащий «полезную» функцию:

using System;

namespace UsefulLibrary {

public class UsefulClass {

public void Print() {

Console.WriteLine("Useful function");

}

}

}

Скомпилируем данный класс как DLL:

c:\TEMP\Test>csc /t:library UL.cs

Пусть основное приложение (файл main.cs) собирается использовать код из сборки UL.dll:

using System;

// подключаем требуемое пространство имен

using UsefulLibrary;

 

class MainClass {

static void Main() {

// используем класс

UsefulClass a = new UsefulClass();

a.Print();

Console.ReadLine();

}

}

Если UL.dll рассматривается как локальная сборка, то она должна находиться в том же каталоге[6], что и основное приложение main.exe как при компиляции, так и при выполнении приложения. Скомпилируем основное приложение main.cs:

c:\TEMP\Test>csc /r:UL.dll main.cs

Ключ компилятора /r (или /reference) позволяет установить ссылку на требуемую сборку.

Применением локальных сборок достигается простота развертывания приложения (все его компоненты сосредоточены в одном месте) и изолированность компонентов приложения. Имя локальной сборки – слабое имя – это имя файла сборки без расширения.

Хотя использование локальных сборок имеет свои преимущества, иногда необходимо сделать сборку общедоступной. До появления .NET Framework основным был подход, при котором код общих библиотек помещался в системный каталог простым копированием фалов при установке программ. Такой подход привел к проблеме, известной как «ад DLL» (DLL Hell). Новое установленное приложение могло заменить требуемую библиотеку новой версией, причем сделать это так, что приложения, ориентированные на старую версию библиотеки, переставали работать. Для решения проблемы DLL Hell в .NET Framework используется специальное защищенное хранилище сборок (Global Assembly Cache, GAC).



Сборки, помещаемые в GAC, должны удовлетворять определенным условиям. Во-первых, такие глобальные сборки должны иметь цифровую подпись. Это исключает подмену сборок злоумышленниками. Во-вторых, для глобальных сборок отслеживаются версии, и вполне допустимой является ситуация, когда в GAC находятся разные версии одной и той же сборки, используемые разными приложениями.

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

Name, Version=1.2.0.0, Culture=neutral, PublicKeyToken=1234567812345678

Сильное имя включает собственно имя главного файла сборки без расширения, версию сборки, указание о региональной принадлежности сборки и маркер открытого ключа сборки.

Рассмотрим процесс создания строго именованной сборки на примере сборки UL.dll. Первое: необходимо создать пару криптографических ключей для цифровой подписи сборки. Для этих целей служит утилита sn.exe, входящая в состав Microsoft .NET Framework SDK.

sn -k keys.snk

Параметр -k указывает на создание ключей, keys.snk – это файл с ключами. Просмотреть полученные ключи можно, используя команду sn -tp.

Далее необходимо подписать сборку полученными ключами. Для этого используется специальный атрибут уровня сборки AssemblyKeyFile:

using System;

using System.Reflection;

 

[assembly: AssemblyKeyFile("keys.snk")]

 

namespace UsefulLibrary { . . . }

Обратите внимание: для использования атрибута необходимо подключить пространство имен System.Reflection; в качестве параметра атрибута указывается полное имя файла с ключами; атрибут должен располагаться вне любого пространства имен.

После подписывания сборку можно поместить в GAC. Простейший вариант сделать это – использовать утилиту gacutil.exe, входящую в состав .NET Framework SDK. При использовании ключа /i сборка помещается в GAC, а ключ /u удаляет сборку из GAC:

gacutil /i ul.dll

Теперь сборка UL.dll помещена в GAC. Ее сильное имя (для ссылки в программах) имеет вид:

UL, Version=0.0.0.0, Culture=neutral, PublicKeyToken= ff824814c57facfe

Компонентом сильного имени является версия сборки. Если программист желает указать версию, то для этого используется атрибут AssemblyVersion. Номер версии имеет формат Major.Minor.Build.Revision. Если номер версии задается, то часть Major является обязательной. Любая другая часть может быть опущена (в этом случае она полагается равной нулю). Часть Revision можно задать как *, тогда компилятор генерирует ее как количество секунд, прошедших с полуночи, деленное на два. Часть Build также можно задать как *. Для нее будет подставлено количество дней, прошедших с 1 февраля 2000 года. Пример использования атрибута AssemblyVersion:

using System;

using System.Reflection;

 

[assembly: AssemblyVersion("1.2.3.*")]

. . .

2.14. КОНФИГУРИРОВАНИЕ сборок

Необходимость конфигурирования сборок обычно возникает при развертывании приложений. Платформа .NET предлагает стандартизированный подход к конфигурированию, основанный на использовании конфигурационных XML-файлов. Специальное пространство имен System.Configuration отвечает за работу с файлами конфигураций.

Рассмотрим общую схему файла конфигурации. Корневым элементом файла всегда является элемент configuration. Некоторые подчиненные элементы описаны далее:

· startup – совокупность параметров запуска приложения;

· runtime – параметры времени выполнения. Они регулируют способ загрузки сборок и сборку мусора;

· system.runtime.remoting – параметры конфигурирования, необходимые для настройки механизма .NET Remoting;

· system.diagnostics – совокупность диагностических параметров, которые задает способ отладки приложений, перенаправляют сообщения отладки и т. д.;

· system.web – параметры конфигурации приложений ASP.NET.

Платформа .NET Framework имеет один файл конфигурации компьютера с параметрами, относящимися к системе в целом. Этот файл называется machine.config. Любая сборка может иметь собственный конфигурационный файл. Он должен носить имя файла сборки (с расширением) с добавленным окончанием .config и располагаться в одном каталоге со сборкой. Таким образом, файл конфигурации для main.exe должен называться main.exe.config. В случае web-приложений файл конфигурации всегда называется web.config.

Разберем на примерах некоторые возможности конфигурирования. Рассмотрим подробнее структуру секции runtime:

<configuration>

<runtime>

<developmenMode>

<assemblyBinding>

<probing>

<publisherPolicy>

<qualifyAssembly>

<dependentAssembly>

<assemblyIdentity>

<bindingRedirect>

<codeBase>

<publisherPolicy>

<gcConcurrent>

 

<developmenMode>

Прототип тэга:

<developmenMode developerInstallation = "true" | "false"/>

Если параметр тэга равен "true", то среда исполнения помимо обычных каталогов пытается искать сборки в каталогах, указанных в переменной среды окружения DEVPATH.

<assemblyBinding>

Тэг служит для объединения группы вложенных элементов

<probing>

Прототип тэга:

<probing privatePath = "paths"/>

Тэг используется для указания подкаталогов, в которых производится поиск локальных сборок приложения. Например, пусть основное приложение AppMain.exe размещено в каталоге C:\Test, и оно использует сборку Add1.dll из каталога C:\Test\bin и сборку Add2.dll из каталога C:\Test\bin\bin2. Тогда для корректного запуска основного приложения файл AppMain.exe.config должен иметь следующий вид:

<configuration>

<runtime>

<assemblyBinding>

<probing privatePath = "bin;bin\bin2"/>

</assemblyBinding>

</runtime>

</configuration>

<publisherPolicy>

Прототип тэга:

<publisherPolicy apply = "yes" | "no"/>

Пусть приложение использует некую стороннюю библиотеку. Если в тэге <publisherPolicy> определен параметр "yes" (по умолчанию), то при установке новой версии библиотеки, приложение автоматически будет использовать эту новую версию. В случае параметра "no" приложение откажется работать с новой версией.

<qualifyAssembly>

Прототип тэга:

<qualifyAssembly partialName="PartName" fullName="FullName"/>

Этот тэг позволяет ассоциировать сокращенное имя сборки с полным строгим именем для удобства использования в программе. Рассмотрим следующий пример:

<configuration>

<runtime>

<assemblyBinding>

<qualifyAssembly

partialName = "Strong"

fullName = "Strong, version=1.2.0.0,

culture=neutral,

publicKeyToken=1234567812345678"/>

</assemblyBinding>

</runtime>

</configuration>

Конфигурационный файл данного примера позволит везде в программе вместо длинного строго имени использовать короткий псевдоним Strong.

<dependentAssembly>

Этот тэг позволяет настроить загрузку персонально для каждой сборки, связанной с основным приложением. Он сам является пустым и объединяет элементы <assemblyIdentity>, <bindingRedirect>, <codeBase>, <publisherPolicy>. Элемент должен быть указан для каждой сборки, политику загрузки которой мы собираемся настраивать.

<assemblyIdentity>

Прототип тэга:

<assemblyIdentity

name = "assembly Name" publicKeyToken = "public key token"

culture = "assembly culture"/>

Тэг идентифицирует сборку

<bindingRedirect>

Прототип тэга:

<bindingRedirect

old version = "old assembly version"

new version = "new assembly version"/>

Тэг позволяет подменить версию сборки, которая будет загружаться приложением. Рассмотрим пример:

<configuration>

<runtime>

<assemblyBinding>

<dependentAssembly>

<assemblyIdentity name = "myAssembly"

publicKeyToken="32ab4ba45e0a69a1"

culture = "neutral"/>

<bindingRedirect oldVersion = "1.0.0.0"

newVersion = "2.0.0.0"/>

</dependentAssembly>

</assemblyBinding>

</runtime>

</configuration>

Теперь, если основное приложение запросит сборку myAssembly версии 1.0.0.0, то, ничего не зная об этом, получит сборку версии 2.0.0.0.

<codeBase>

Прототип тэга:

<codeBase version="assembly version" href="URL of assembly"/>

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

<configuration>

<runtime>

<assemblyBinding>

<dependentAssembly>

<assemblyIdentity name = "myAssembly"

publicKeyToken = "32ab4ba45e0a69a1"

culture = "neutral"/>

<codeBase version = "1.0.0.0"

href = "http://localhost/one/Strong.dll"/>

</dependentAssembly>

</assemblyBinding>

</runtime>

</configuration>

Этот конфигурационный файл предписывает загружать среде исполнения сборку Strong из Интернета по адресу http://localhost/one/Strong.dll.

<gcConcurrent>

Прототип тэга:

<gcConcurrent enabled = "true" | "false"/>

Если параметр enabled установлен в true, то «сборка мусора» происходит в параллельном потоке по отношению к основному приложению. Это поведение по умолчанию.

Рассмотрим задачу размещения собственных данных в конфигурационном файле сборки. В простейшем варианте для этого используется секция appSettings. Данная секция может содержать следующие элементы:

· <add key = "name" value = "the value"/> – добавляет новый ключ и значение в коллекцию конфигурационных элементов;

· <remove key = "name"/> – удаляет существующий ключ и значение из коллекции конфигурационных элементов;

· <clear/> – очищает коллекцию конфигурационных элементов.

Для работы с данными секции appSettings используется класс ConfigurationSettings из пространства имен Sistem.Configuration. Статическое свойство AppSettings представляет собой коллекцию, позволяющую получить строковое значение конфигурационного элемента по ключу.

Пусть имеется следующее консольное приложение main.exe:

using System;

using System.Configuration;

 

class MainClass {

static void Main() {

string v1 = ConfigurationSettings.AppSettings["key1"];

string v2 = ConfigurationSettings.AppSettings["key2"];

Console.WriteLine(v1);

Console.WriteLine(v2);

Console.ReadLine();

}

}

Создадим для этого приложения конфигурационный файл main.exe.config:

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

<configuration>

<appSettings>

<add key="key1" value="Alex" />

<add key="key2" value="Volosevich" />

</appSettings>

</configuration>

Результат выполнения main.exe:

Alex

Volosevich

Все секции конфигурационного файла разбираются специальными классами-обработчиками (section handlers). Такой класс реализует интерфейс System.Configuration.IConfigurationSectionHandler. В составе .NET Framework имеется несколько готовых классов-обработчиков: NameValueSectionHandler, IgnoreSectionHandler, DictionarySectionHandler, SingleTagSectionHandler.

Чтобы описать в конфигурационном файле собственную секцию, следует использовать тэг configSections. Вложенные элементы section данного тэга имеют атрибут name – имя секции, и атрибут type – полное имя класса-обработчика. Рассмотрим следующий пример конфигурационного файла:

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

<configuration>

<configSections>

<section name = "mySection"

type = "System.Configuration.NameValueSectionHandler" />

</configSections>

 

<mySection>

<add key="key1" value="Alex" />

<add key="key2" value="Volosevich" />

</mySection>

</configuration>

Этот файл задает пользовательскую секцию с именем mySection и указывает, что для ее обработки следует использовать NameValueSectionHandler, то есть, содержимое секции будет доступно как NameValueCollection.

Для чтения информации из пользовательской секции применяется метод ConfigurationSettings.GetConfig(). В качестве параметра методу передается имя секции. Метод возвращает значение типа object, которое следует привести к типу класса-обработчика секции. Следующее приложение читает информацию из своего (описанного выше) конфигурационного файла:

using System;

using System.Configuration;

using System.Collections.Specialized;

 

class CustomConfig {

static void Main() {

NameValueCollection nvc =

(NameValueCollection)ConfigurationSettings.GetConfig("mySection");

Console.WriteLine(nvc["key1"]);

Console.WriteLine(nvc["key2"]);

}

}

Следует иметь в виду, что файл конфигурации читается и разбирается исполняемой средой один раз, при загрузке приложения. Поэтому все изменения, которые внесены в этот файл, не буду иметь эффекта до перезагрузки приложения. Если такое поведение является неприемлемым, то можно воспользоваться классом System.IO.FileSystemWatcher. Как следует из его названия, класс позволяет отследить изменения, происходящие с файлом (или несколькими файлами). Подробности работы с классом FileSystemWatcher можно найти в .NET Framework SDK.


3.1. ДОМЕНЫ ПРИЛОЖЕНИЙ

Любому запущенному приложению в операционной системе соответствует некий процесс. Процесс образует границы приложения, и для взаимодействия процессов требуется применять специальные средства. В .NET Framework процессы дополнительно подразделяются на домены приложений. Один домен может содержать несколько сборок. Различным доменам могут соответствовать различные политики безопасности, домены могут создаваться и уничтожаться в ходе работы в рамках одного приложения.

Рассмотрим работу с доменами на примерах. Пусть имеется следующая сборка, размещенная в динамической библиотеке Students.dll:

using System;

 

public class Student {

public string Name;

public int Age;

public double MeanScore;

public Student(string Name, int Age, double MeanScore) {

this.Name = Name;

this.Age = Age;

this.MeanScore = MeanScore;

log.print("New Student object created");

}

public void sayName() {

log.print("sayName() is called");

Console.WriteLine("My name is {0}", Name);

}

}

 

public class log {

public static void print(string s) {

Console.WriteLine("[{0}]: {1}",

AppDomain.CurrentDomain.FriendlyName,s);

}

}

Домены приложений инкапсулированы в объектах класса System.AppDomain. Любое приложение при запуске создает домен по умолчанию, в который загружается главная сборка приложения. Для создания нового домена используется статический метод AppDomain.CreateDomain(). Существует несколько перегруженных версий этого метода, которые обеспечивают применение к создаваемому домену определенных политик безопасности. В простейшем случае методу передается в качестве параметра только строка с дружественным именем домена, которое используется как идентификатор домена:

AppDomain ad2 = AppDomain.CreateDomain("New Domain");

После создания домена в него можно загрузить сборки, используя метод Load()[7] (указывается слабое или сильное имя сборки):

ad2.Load("Students");

Отдельную сборку выгрузить из домена нельзя, но можно выгрузить домен целиком, используя его метод Unload():

AppDomain.Unload(ad2);

В любом домене можно создавать объекты различных типов. Данные действия выполняются при помощи методов CreateInstance(), CreateInstanceFrom(), CreateInstanceAndUnwrap(), CreateInstanceFromAndUnwrap(). Рассмотрим подробнее метод CreateInstance(). Существует несколько перегруженных версий этого метода. В простейшем случае в качестве параметров метода указывается имя сборки и полное имя типа. Самый полный вариант CreateInstance() имеет следующую сигнатуру:

public virtual ObjectHandle CreateInstance(

string assemblyName,

string typeName,

bool ignoreCase,

BindingFlags bindingAttr,

Binder binder,

object[] args,

CultureInfo culture,

object[] activationAttributes,

Evidence securityAttributes);

Опишем параметры метода CreateInstance(). Первый параметр указывает имя сборки, содержащей тип создаваемого объекта. Сборка может быть загружена в домен, хотя это и не обязательно. Второй параметр – строка с полным именем создаваемого типа. При помощи третьего параметра можно сделать поиск типа в сборке регистронезависимым. Четвертый параметр позволяет задать область поиска конструктора типа. Если данный параметр равен нулю, выполняется регистрозависимый поиск public-конструктора типа[8]. Параметр binder позволяет указать особый способ связывания и подстановки вызовов методов и полей. Обычно используется способ по умолчанию (значение параметра – null). Следующим указывается массив, содержащий параметры конструктора. Параметр culture указывает культуру создаваемого объекта (актуально для приложений, настраиваемый на локализацию). Предпоследний параметр позволяет задать массив объектов-атрибутов, участвующих в активации создаваемого объекта. Последний параметр управляет атрибутами безопасности создаваемого объекта.

Метод CreateInstanceFrom() практически идентичен CreateInstance(), но сборка загружается из указанного файла. В следующем фрагменте кода происходит создание нового домена приложения и создание объекта типа Student в этом домене:

AppDomain ad2 = AppDomain.CreateDomain("New Domain");

ad2.CreateInstanceFrom(@"C:\Students.dll", // Имя файла сборки

"Student", // Имя класса

false, // Регистрозависимый поиск

// Указываем, что ищем конструктор

// Хотя с таким же успехом можно написать 0

BindingFlags.CreateInstance,

null, // Особой привязки не используем

// Параметры конструктора

new object[]{"Ivanov", 20, 4.5},

null, // Остальные параметры игнорируем

null, // или принимаем по умолчанию

null);

Приведенный фрагмент кода демонстрирует создание объекта в другом домене, однако дальнейшая работа с объектом невозможна – мы просто не имеем никакой ссылки на созданный объект. Технология передачи объектов через границы доменов (процессов) называется маршалинг. Пусть имеются два домена – D1 и D2. Предположим, что в домене D1 требуется производить работу с объектом Obj из домена D2. При маршалинге возможна передача объектов как по ссылке, так и по значению. В случае передачи по значению в домене D1 будет создана локальная копия объекта Obj из D2. Естественно, все изменения, внесенные в Obj из D1 не отразятся на Obj из D2.

В случае передачи объекта по ссылке среда исполнения использует специальный объект-прокси (посредник) Pr, который в домене D1 выглядит как объект Obj, но фактически перенаправляет все вызовы своих методов к объекту Obj в домене D2.

Простейший способ осуществить маршалинг объектов по значению – пометить тип как сериализуемый (атрибутом [Serializable]). Пусть таким образом помечен тип Student. В предыдущем примере значение, возвращаемое CreateInstance(), игнорировалось. В следующем фрагменте это значение приводится к типу Student, и демонстрируется работа с элементами созданного объекта:

using System;

using System.Reflection;

using System.Runtime.Remoting;

 

class MainClass {

public static void Main() {

AppDomain ad2 = AppDomain.CreateDomain("New Domain");

ObjectHandle oh = ad2.CreateInstanceFrom(

@"C:\Temp\Students.dll", "Student",

false, BindingFlags.CreateInstance,

null,

new object[]{"Ivanov", 20, 4.5},

null, null, null);

Student s = (Student)oh.Unwrap();

s.sayName();

s.Name = "Petrov";

s.sayName();

Student s_new = (Student)oh.Unwrap();

s_new.sayName();

}

}

Вот что выводит данная программа на консоль:

[New Domain]: New Student object created

[AppDom.exe]: sayName() is called

My name is Ivanov

[AppDom.exe]: sayName() is called

My name is Petrov

[AppDom.exe]: sayName() is called

My name is Ivanov

Как видим, объект был создан в одном домене, но затем копия объекта была перемещена в другой домен, где с ней и происходила работа.

Обратите внимание: метод CreateInstanceFrom() возвращает объект специального класса ObjectHandle. Данный класс реализует «обертки» над реальными объектами, что позволяет не передавать через границы доменов метаданные. Для получения реального объекта используется экземплярный метод ObjectHandle.Unwrap(), который возвращает либо объект, либо прокси. Метод CreateInstanceFromAndUnwrap() выполняет «разворачивание» созданного объекта автоматически.

Чтобы передача объектов некоторого типа между границами доменов происходила по ссылке, требуется, чтобы тип был унаследован от типа MarshalByRefObject. Если допустить, что тип Student унаследован от этого типа, то предыдущий пример выведет на консоль следующее:

[New Domain]: New Student object created

[New Domain]: sayName() is called

My name is Ivanov

[New Domain]: sayName() is called

My name is Petrov

[New Domain]: sayName() is called

My name is Petrov

В завершение приведем таблицу, содержащую некоторые методы и свойства класса System.AppDomain.

Таблица 17

Некоторые элементы класса System.AppDomain

Имя элемента Описание
CurrentDomain Статическое свойство, возвращающее текущий домен текущего потока
CreateDomain() Статический метод для создания домена
GetCurrentThreadID() Статическое свойство, возвращает идентификатор текущего потока
Unload() Статический метод который удаляет указанный домен
FriendlyName Строка с именем домена
DefineDynamicAssembly() Метод позволяет динамически создавать сборки
ExecuteAssembly() Метод запускает на выполнение указанную сборку
GetData() Метод позволяет получить данные, сохраненные в домене под неким именем-ключом
Load() Метод загружает сборки в домен
SetAppDomainPolicy() Метод для установки политики безопасности домена
SetData() Метод позволяет сохранить данные в домене под неким именем-ключом

3.2. Архитектура .NET Remoting

В настоящее время все большее распространение получают распределенные приложения. В распределенном приложении (distributed application) отдельные компоненты выполняются на различных компьютерах, которые связаны сетью передачи данных. Как правило, компонент распределенного приложения реализует некий сервис, иначе говоря, предоставляет определенные услуги, доступные путем вызова методов компонента. Сам компонент является объектом некоторого класса. Таким образом, создание распределенного приложения подразумевает возможность вызова на одном компьютере методов объекта, размещенного на другом компьютере.

Введем некоторые термины, которые используются в дальнейшем. Рассматривая распределенное приложение, будем выделять клиент и сервер. Сервер содержит удаленные компоненты, клиент пользуется данными компонентами. Компонентам соответствуют классы. Эти классы будем называть удаленными классами (по отношению к клиенту), а объекты удаленных классов – удаленными объектами.

Для вызова методов удаленных объектов и клиент и сервер могут использовать традиционные подходы сетевого программирования. А именно:

1.Клиент должен обеспечить соединение с сервером и передачу серверу в закодированном виде имени класса, имени метода и параметров метода.

2.Сервер организует прослушивание сообщений от клиентов и их обработку (желательно в отдельных потоках выполнения).

3.Обработка сообщений клиентов подразумевает декодирование имени метода и параметров, фактический вызов соответствующего метода, кодирование результата и отправку его клиенту.

4.Клиент принимает закодированные результаты, декодирует их и возвращает как результат вызова метода.

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

Технологии, подобные .NET Remoting[9] (далее для краткости – Remoting), служат универсальным средством для организации работы с удаленными объектами. Remoting тесно интегрирована с исполняющей средой .NET Framework, а также предоставляет множество средств для тонкой настройки своей инфраструктуры.



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


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


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

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

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


 


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

 
 

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

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