chitay-knigi.com » Разная литература » Интернет-журнал "Домашняя лаборатория", 2007 №6 - Усманов

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 239 240 241 242 243 244 245 246 247 ... 361
Перейти на страницу:
в приоритетном порядке по отношению к асинхронным. Однако в случае реализации атрибута синхронизации в рамках SSCLI это не так — попавшие в очередь (единую для всего домена синхронизации) работы извлекаются из нее в порядке очереди, и тип работы (синхронный или асинхронный вызов) не влияет на этот порядок.

Эксперименты

Эксперименты с вышеописанным кодом должны продемонстрировать работу сервисов синхронизации и трассировки вызовов.

Все компоненты размещаются в одном контексте

Первый эксперимент не требует какой-либо модификации кода клиента и сервера. Каждому компоненту (Account, Tax, News) приписаны два атрибута:

[Synchronization ()]

[MyCallTrace("LogFile")]

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

Запустив серверное приложение и параллельно два клиентские приложения, мы увидим на консоли сервера информацию о том, что все три компонента выполняются в контексте 1.

Ниже приведены несколько первых строк с консоли сервера

Server is listening

News context = 1 News constructor thread = 3 IsPoolThread = True

Tax context = 1 Tax constructor thread = 3 IsPoolThread = True

Account context = 1 Account constructor thread = 3 IsPoolThread = True

Tax notification: new Account operation: +5

Tax Notify thread = 3 IsPoolThread = True

News notification: new Account operation: +5

News Notify thread = 3 IsPoolThread = True

News notification: direct notification from Account

News Notify thread = 3 IsPoolThread = True

Account Add thread = 3 IsPoolThread = True

Tax notification: new Account operation: +5

Tax Notify thread = 65 IsPoolThread = True

News notification: new Account operation: +5

News Notify thread = 65 IsPoolThread = True

News notification: direct notification from Account

News Notify thread = 65 IsPoolThread = True

Account Add thread = 65 IsPoolThread = True

Tax notification: new Account operation: +5

Tax Notify thread = 3 IsPoolThread = True

News notification: new Account operation: +5

News Notify thread = 3 IsPoolThread = True

News notification: direct notification from Account

News Notify thread = 3 IsPoolThread = True

Account Add thread = 3 IsPoolThread = True

…….

Еще одно замечание, связанное с консолью сервера — конструкторы компонентов выполняются в одном рабочем потоке, а далее эти компоненты вызываются двумя рабочими потоками. Эти потоки, конечно, никак не связаны с клиентами. Можно модифицировать код клиента и сервера, передавая при вызове метода Add не только сумму вклада, но и идентификатор процесса, в котором исполняется клиент, сделавший вызов. После этого можно заметить, что оба рабочих потока выполняют вызовы клиентов не зависимо от процесса клиента. Да и число рабочих потоков не связано напрямую с числом клиентов.

Модификация кода сервера (MyServer.cs) связана с добавлением интерфейса IAccumuiatorNew:

……

namespace SPbU.AOP_NET {

public interface IAccumuiatorNew{

       void Add(int sum, int clientProcessId);

}

……

public class Account: ContextBoundObject, IAccumulator,

       IAudit, IAccumuiatorNew!

……

       public void Add(int sum, int clientProcessId){

           _sum += sum;

           _tax.Notify("new Account operation: +" + sum);

           _tax.news.Notify("direct notification from Account");

           Console.WriteLine("Account Add thread = " +

                Thread.CurrentThread.GetHasheode() +

                " IsPoolThread = " +

               Thread.CurrentThread.IsThreadPoolThread +

               " clientProcessId ="+ clientProcessId);

       }

……

Необходимая модификация клиента (MуАрр. cs) представлена ниже

…….

using System.Diagnostics;

public class MyApp {

    public static void Main() {

           HttpChannel с = new HttpChannel();

           ChannelServices.RegisterChannel(c);

           Process p = Process.GetCurrentProcess();

           try {

……

                for (int i=0; i<100; i++) {

                   a. Add(5, p.Id);

              }

…….

       }

…….

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

Account Add thread = 65 IsPoolThread = True clientProcessId =192

Tax notification: new Account operation: +5

Tax Notify thread = 65 IsPoolThread = True

News notification: new Account operation: +5

News Notify thread = 65 IsPoolThread = True

News notification: direct notification from Account

News Notify thread = 65 IsPoolThread = True

Account Add thread = 65 IsPoolThread = True clientProcessId =192

Tax notification: new Account operation: +5

Tax Notify thread = 3 IsPoolThread = True

News notification: new Account operation: +5

News Notify thread = 3 IsPoolThread = True

News notification: direct notification from Account

News Notify thread = 3 IsPoolThread = True

Account Add thread = 3 IsPoolThread = True clientProcessId =165

Tax notification: new Account operation: +5

Tax Notify thread = 3 IsPoolThread = True

News notification: new Account operation: +5

News Notify thread = 3 IsPoolThread = True

News notification: direct notification from Account

News Notify thread = 3 IsPoolThread = True

…….

Еще стоит обратить внимание на то, что рабочий поток, выполняющий вызов метода Add компонента Account, выполняет и вызовы метода Notify для компонентов Tах и News, инициированные из компонента Account. Причина в том, что в рамках данного эксперимента все три компонента находятся в одном контексте синхронизации, и поток, вошедший в этот контекст, не выходит из него, пока не будут сделаны все вышеупомянутые вызовы. Только после этого другой поток может войти в данный контекст и начать выполнение метода Add.

Просмотрев файл LogFile, в который выполняется запись данных о перехваченных вызовах, можно заметить, что трассируются только вызовы к компоненту Account. Это объясняется тем, что именно компонент Account получает вызовы извне контекста (от клиентов), и эти вызовы перехватываются перехватчиком входящих вызовов атрибута трассировки. Вызовы, которые делаются к компонентам Tах и News, идут от компонентов Account и Tах и не пересекают границу контекста. Именно поэтому они и не перехватываются. Первые строки файла LogFile представлены ниже:

===SPbU.AOP_NET.Account, MyServer, Version=0.0.0.0,

     Culture=neutral, PublicKeyToken=null

ctor

     

1 ... 239 240 241 242 243 244 245 246 247 ... 361
Перейти на страницу:

Комментарии
Минимальная длина комментария - 25 символов.
Комментариев еще нет. Будьте первым.