Воскресенье, 19.05.2024, 04:47
Приветствую Вас Guest Member

Windows XP / 7 .

[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 2 из 2
  • «
  • 1
  • 2
Архив - только для чтения
Форум <<Помощь по компьютерам>> » Низкоуровневое программирование » Исходные коды » Исходные коды: C# (Исходные коды: C#)
Исходные коды: C#
MafiozikOДата: Суббота, 22.08.2009, 23:38 | Сообщение # 16
~Web master~
Группа: Gold пользователь
Зарегистрирован: 10.04.2009
Откуда: Kharkiv
Пол: Мужчина
Сообщений: 366
Статус: Вне сайта
Использование фиктивных граничных объектов дает максимальную эффективность при добавлении и удалении элементов, так как эти операции всегда происходят в предположении, что элемент имеет как предыдущего, так и последующего соседа. В целом реализация списка достаточно традиционна, но особо следует отметить поле currentPrev. В начале итерации (при вызове метода GetFirst) это поле устанавливается в null, а после получения очередного активного объекта (GetNext) изменяется на предыдущий активный объект. Поскольку активный объект в ходе своего выполнения может деактивировать себя, то ссылка на следующий объект будет потеряна. Ситуация еще больше усложняется, если объект деактивирует не только себя, но и своих соседей. Для решения этой задачи и служит currentPrev. Корректировка currentPrev выполняется в методе Remove. Если объект деактивируется (удаляется из списка) и, при этом, он является currentPrev, то currentPrev вначале переводится на предыдущий объект и только потом объект удаляется. Таким образом, currentPrev всегда ссылается на объект, который находится в списке и предшествует текущему объекту, но не обязательно является его ближайшим соседом.

При активации объекта (добавлении его в список) выполняется три проверки:

* контроль неактивности объекта. Неактивность определяется тем, что поле next объекта равно null, то есть, у него еще нет соседа;
* контроль отсутствия фатальной ошибки. Если объект содержит непустую ссылку на исключительную ситуацию, то он был завершен с фатальной ошибкой (необработанной исключительной ситуацией) и не может быть активирован вновь;
* контроль отсутствия состояния ожидания. Если поле sleeping объекта имеет значение true, то объект стал неактивным в результате вызова одного из методов Sleep и может быть активирован только с помощью WakeUp.

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

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

Изменение списка выполняется в критических секциях (lock), что позволяет активировать и деактивировать объекты из других нитей приложения.


Админ
 
MafiozikOДата: Суббота, 22.08.2009, 23:39 | Сообщение # 17
~Web master~
Группа: Gold пользователь
Зарегистрирован: 10.04.2009
Откуда: Kharkiv
Пол: Мужчина
Сообщений: 366
Статус: Вне сайта
Протокол

Назначение протокола - хранение списка активных объектов, которые были аварийно завершены по необработанной исключительной ситуации.

Code
private class Log
{
   private List<ActiveObject> list;

   public Log()
   {
     list = new List<ActiveObject>();
   }

   public void Add(ActiveObject obj)
   {
     lock (this)
     {
       list.Add(obj);
     }
   }

   public ActiveObject[] Get()
   {
     ActiveObject[] result = null;
     lock (this)
     {
       if (list.Count != 0)
       {
         result = list.ToArray();
         list.Clear();
       }
     }
     return result;
   }

   public void Clear()
   {
     lock (this)
     {
       list.Clear();
     }
   }
}


Админ
 
MafiozikOДата: Суббота, 22.08.2009, 23:39 | Сообщение # 18
~Web master~
Группа: Gold пользователь
Зарегистрирован: 10.04.2009
Откуда: Kharkiv
Пол: Мужчина
Сообщений: 366
Статус: Вне сайта
Активатор

Назначение активатора - циклическая итерация по всем активным объектам и вызов их метода Step. Активатор создает свою собственную нить, в контексте который и выполняются все активные объекты.

Code
private class Activator
{
   private Thread thread;
   private bool terminate;

   private void Execute()
   {
     ActiveObject obj;
     while (!terminate)
     {
       if (dispatcher.Count != 0)
       {
         obj = dispatcher.GetFirst();
         while (obj != null)
         {
           try
           {
             obj.Step();
           }
           catch (Exception e)
           {
             obj.exception = e;
             dispatcher.Remove(obj);
             log.Add(obj);
           }
           obj = dispatcher.GetNext();
         }
       }
       else
         Thread.Sleep(1);
       for (obj = timer.GetReady(); obj != null; obj = timer.GetReady())
         dispatcher.WakeUpByTimer(obj);
     }
   }

   public void Start(ThreadPriority priority)
   {
     lock (this)
     {
       if (thread == null)
       {
         terminate = false;
         thread = new Thread(new ThreadStart(Execute));
         thread.Priority = priority;
         thread.Start();
       }
     }
   }

   public void Stop()
   {
     lock (this)
     {
       if (thread != null)
       {
         terminate = true;
         thread.Join();
         thread = null;
       }
     }
   }
}


Админ
 
MafiozikOДата: Суббота, 22.08.2009, 23:39 | Сообщение # 19
~Web master~
Группа: Gold пользователь
Зарегистрирован: 10.04.2009
Откуда: Kharkiv
Пол: Мужчина
Сообщений: 366
Статус: Вне сайта
Таймер

Таймер представляет собой список временно неактивных объектов. Объекты попадают к таймеру при выполнении метода Sleep. Список сортируется по убыванию времен, и, таким образом, объекты с меньшими значениями времени ожидания (timeout) размещаются в конце списка. Сортировка в обратном порядке дает большую эффективность, так как объекты, завершившие свое ожидание, удаляются из конца (а не из начала) списка. К сожалению, библиотека .Net Framework не имеет контейнера, который можно использовать в данном случае. Наиболее подходящий контейнер, SortedList, требует уникальных значений ключей, а время ожидания для нескольких объектов может совпадать.

Code

private class Timer : : IComparer<ActiveObject>
{
   private List<ActiveObject> list;

   public Timer()
   {
     list = new List<ActiveObject>();
   }

   public int Compare(ActiveObject obj1, ActiveObject obj2)
   {
     return obj2.timeout - obj1.timeout;
   }

   public void Add(ActiveObject obj)
   {
     lock (this)
     {
       int i = list.BinarySearch(obj, this);
       if (i < 0)
         i = ~i;
       list.Insert(i, obj);
     }
   }

   public void Clear()
   {
     lock (this)
     {
       list.Clear();
     }
   }

   public ActiveObject GetReady()
   {
     lock (this)
     {
       int H = list.Count - 1;
       if (H >= 0)
       {
         ActiveObject obj = list[H];
         if (Environment.TickCount >= obj.timeout)
         {
           list.RemoveAt(H);
           return obj;
         }
       }
     }
     return null;
   }
}


Админ
 
Форум <<Помощь по компьютерам>> » Низкоуровневое программирование » Исходные коды » Исходные коды: C# (Исходные коды: C#)
  • Страница 2 из 2
  • «
  • 1
  • 2
Поиск: