|
Программирование >> Программирование с использованием ajax
В роли первичного ключа для этой строки выступает идентификатор рабочего потока, а в ее втором столбце содержатся бинарные сериализованные данные состояния рабочего потока на момент его сохранения. Значение в столбце nextTimer показывает, когда завершится выполнение действия DelayActivity, и рабочий поток будет сразу же (или некоторое время спустя, в зависимости от интервала опроса) загружен снова. По истечении периода времени, определенного в DelayActivity, рабочий поток загружается снова, на что указывает сообщение Loaded, после этого он завершается, что приводит к генерации еще одного события обеспечения постоянства (Persisted). При сохранении завершившегося рабочего потока, представлявшая его строка в таблице InstanceState удаляется. При желании принудительно применить точку обеспечения постоянства в специальном действии, вроде показанного выше действия DebugActivity, можно добавить к действию атрибут PersistOnCloseAttribute: [ActivityValidator(typeof(DebugActivityValidator))] [Designer(typeof(DebugActivityDesigner))] [PersistOnClose] public class DebugActivity : Activity Добавление двух отладочных действий в рабочий поток - одного выше и одного ниже DelayActivity - приведет к отображению в окне консоли такого вывода: Workflow 005f5924-fb49-4d60-a8bd-f572al9ald39 Persisted - А Workflow 005f5924-fb49-4d60-a8bd-f572al9ald39 Idled Workflow 005f5924-fb49-4d60-a8bd-f572al9ald39 Persisted Workflow 005f5924-fb49-4d60-a8bd-f572al9ald39 Unloaded Workflow 005f5924-fb49-4d60-a8bd-f572al9ald39 Loaded Workflow 005f5924-fb49-4d60-a8bd-f572al9ald39 Persisted В Workflow 005f5924-fb49-4d60-a8bd-f572al9ald39 Persisted Здесь видны два дополнительных события обеспечения постоянства (Persisted), помеченные символами А и В. Они соответствуют тем двум отладочным действиям, которые были добавлены в рабочий поток. Данным атрибутом, однако, следует пользоваться осторожно: слишком большое количество точек обеспечения постоянства в рабочем потоке может навредить его производительности. Обратите внимание, что в случае использования действия с определенным атрибутом PersistOnClose, обязательно требуется наличие и определенной службы обеспечения постоянства. Главным преимуществом присутствия службы постоянства является возможность возобновления выполнения рабочего потока после его прерывания, например, в результате перебоев в электропитании на сервере, который отвечает за хостинг рабочих потоков. При запуске исполняющей среды рабочих потоков снова, что может произойти как через несколько минут, так и через несколько часов или даже дней, служба постоянства будет отыскивать любые пригодные для запуска рабочие потоки и загружать их для выполнения. То есть в случае нахождения в памяти нескольких рабочих потоков на момент отключения электроэнергии, каждый из них будет возвращаться к тому состоянию, в котором он находился на последнем этапе его сохранения, т.е. к предыдущей точке постоянства, и начинать выполняться оттуда снова. Это позволяет создавать программы (ведь рабочие потоки, по сути, тоже представляют собой программы), способные продолжать свою работу и после прерывания с того этапа, на котором было прервано их выполнение, что является очень мощной концепцией. Привязка данных В завершение этой главы давайте посмотрим, какую роль играет понятие привязки данных (data binding) в контексте рабочих потоков. Типичным сценарием при запуске рабочего потока является необходимость в передаче вместе с потоком по мере его выполнения данных о состоянии. Например, в случае рабочего потока, предназначенного для обслуживания страховых полисов, который описывался ранее в этой главе, вы наверняка бы захотели, чтобы в него передавалась какая-то информация вроде уникального номера страхового полиса, которая могла бы применяться во входящих в состав этого рабочего потока действиях. Для передачи параметров в рабочий поток требуется вносить в код два изменения. Во-первых, необходимо определять в рабочем потоке свойства для каждого параметра, который должен ему передаваться. Во-вторых, нужно передавать эти параметры при запуске рабочего потока. Еще одним важным вопросом, который до этого момента пока не рассматривался, является то, как определять свойства в рабочем потоке. Поскольку рабочий поток представляет собой просто .NET-класс, можно было бы использовать и синтаксис обычных свойств С#. Но другой прием в рабочих потоках позволяет делать кое-какие дополнительные вещи с данными, помимо тех, которые допускается делать с обычными свойствами. За счет применения так называемого свойства зависимостей (DependencyProperty) данные, поступающие в рабочий поток, можно связывать с другими действиями в этом же потоке. Синтаксис, необходимый для определения свойства рабочего потока, выглядит довольно-таки сложно, но того фрагмента кода, который поставляется с .NET, будет вполне достаточно. В следующем практическом занятии демонстрируется пример добавления свойства в рабочий поток и передачи ему значения при запуске этого рабочего потока, а также привязки к этому свойству кое-каких данных. Практическое занятие Определение связанных свойств 1. Создайте еще один новый проект типа рабочего потока и отобразите для него окно кода. Затем отобразите внутри этого окна контекстное меню и выберите в нем пункт Insert Snippet (Вставить фрагмент). В списке типов, который появится далее, выберите тип Workflow (Рабочий поток). Далее выберите из всплывающего меню пункт Dependency Property - Property (Свойство зависимостей - Свойство). Это приведет к добавлению показанного ниже фрагмента кода (в качестве альтернативного варианта, вместо выбора всех этих пунктов из меню добиться создания такого же фрагмента кода можно и просто путем ввода wdp и двух нажатий клавиши <ТаЬ>). public static DependencyProperty NAME}Property = DependencyProperty.Register( {NAME} , typeof({TYPE}), typeof(Workflowl)); [DescriptionAttribute( {NAME} )] [CategoryAttribute( {NAME} Category )] [BrowsableAttribute(true)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public {TYPE} {NAME} get { set { base.SetValue(Workflowl.{NAME}Property, value); Этот фрагмент кода включает два раздела, в которых можно выполнять ввод: раздел {NAME}, в котором можно вводить желаемое имя для свойства, каковым в данном примере должно быть Pol icy Id, и раздел {TYPE}, в котором можно вводить тип данных свойства, каковым в данном примере должен быть тип string. Еще в коде для свойства бросается в глаза то, что вместо использования переменной экземпляра для сохранения значения, выполняется вызов такого метода базового класса, как GetValue () или SetValue (). Класс Activity (от которого наследуется рабочий поток) сам наследуется от класса DependencyObject, и в этом классе как раз и определяются данные методы. На самом деле, в классе DependencyObject содержится словарная коллекция пар типа ключ-значение , которая и служит для сохранения фактического значения свойства. Хотя может показаться, что такого количества кода многовато для определения свойства, есть одно важное преимущество и состоит оно в поддержке привязки данных, которую оно обеспечивает. 2. Действие DebugActivity снова встречается в этом разделе, поскольку первоначально его свойство Message было определено как обычное свойство .NET. А для поддержки привязки данных его определение необходимо обновить. Чтобы сделать это, удалите из определения DebugActivity свойство Message и затем замените его свойством зависимостей. Весь необходимый для этого код выглядит так: [ActivityValidator(typeof(DebugActivityValidator))] [Designer(typeof(DebugActivityDesigner) ) ] [PersistOnClose] public class DebugActivity : Activity { public static DependencyProperty MessageProperty = DependencyProperty.Register( Message , typeof(string), [DescriptionAttribute( Message )] [CategoryAttribute( Details )] [BrowsableAttribute(true)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible) ] public string Message get { return ((string) (base.GetValue(DebugActivity.MessageProperty))) ; set { base.SetValue(DebugActivity.MessageProperty, value); В этом коде определение свойства Message просто заменяется свойством зависимостей с таким же именем и типом данных. Однако перед его использованием в рабочем потоке необходимо еще одно небольшое изменение, которое потребуется внести в код верификатора.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |