Проблема со StateMtatemachine и сервисами
От: Scilur Украина  
Дата: 24.05.07 14:50
Оценка:
Господа, вразумет, пожалуйста, кто может:

Я создаю StateMtatemachine workflow с несколькими состояниями (например, 1, 2 и 3) и переходами между ними (например, 1->2, 2->3, 1->3); присоединяю к ран-тайму сервис, которые может возбудждать события (например ev12 для перехода 1->2, ev23 для перехода 2->3, например ev12 для перехода 1->3). Запускаю ран-тайм и создаю экземпляр своего воркфлоу, после чего, если я вызываю методы сервиса, возбуждая последовтельно события ev12, ev23, то переход 1->2 происходит нормально, а вот привозбуждении события ev23 вы валивается ошибка о невозможности доставить мой ивент к соответствующему воркфлоу. Если после возбуждения ev12 делается небольшая пауза, то и ev23 тоже проходит нориально. Если после ev12 возбуждать сразу же (без паузы) событие ev13, то оно тоже нормально игнорируется.
Может, кто подскажет, где тот критерий критерий когда можно возбуждать следующее событие так, чтобы оно не вызывало ошибку?

Спасибо всем, кто примет участие!
Re: Проблема со StateMtatemachine и сервисами
От: mrozov  
Дата: 24.05.07 15:17
Оценка: 2 (1)
Здравствуйте, Scilur, Вы писали:

S>Может, кто подскажет, где тот критерий критерий когда можно возбуждать следующее событие так, чтобы оно не вызывало ошибку?


S>Спасибо всем, кто примет участие!


Сам я конкретно с такой ситуацией не сталкивался. Однако из общих соображений могу сказать, что при отправке события в workflow оно должно быть помещено в очередь. Очередь эта в определенный момент создается и в определенный момент же уничтожается.

При этом, если ты проведешь эксперимент и попытаешься отправить сообщение в workflow, находящуюся в состоянии, в котором нужного обработчика нет — ты получишь это самое исключение. Т.е. WWF работает таким образом, что событие в workflow можно отправить только тогда, когда оно готово к его обработке. Это не хорошо и не плохо — это просто факт — так вот оно устроено. В противном случае роявились бы другие проблемы.

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

Если по условию задачи события могут возникать в любой момент — ты попал. Нужно проводить редизайн.
Re: Проблема со StateMtatemachine и сервисами
От: Scilur Украина  
Дата: 29.05.07 13:02
Оценка: 2 (1)
Во-первых, большое спасибо всем принявшим участие!
Во-вторых, рад сообщить, что проблема таки развязалась успешно.
Ну и, в-третьих, если кому интересно, сообщаю: дело, действительно, заключается в работе с очередью. И беда тут в том, что при переходе из одного состояния в другое, эта самая очередь становится временно недоступна (конкретней пока ничего не могу сказать). Поэтому, чтобы все события срабатывали нормально, необходимо, чтобы после срабатывания одного события и перед перехватом другого, вся стейт-машина хоть на мгновение, но попала в состояние IDLE. Для этой цели служит аргумент WaitForIdle в классе ExternalDataEventArgs. Выставляя его в TRUE, Вы определяете, что никакое новое событие не будет рассматриваться до тех пор, пока машине не побывает в состоянии IDLE. В результате все начинает работать корректно.
Еще раз всем большое спасибо!
Re[2]: Проблема со StateMtatemachine и сервисами
От: mrozov  
Дата: 29.05.07 14:04
Оценка:
Здравствуйте, Scilur, Вы писали:

S>Во-первых, большое спасибо всем принявшим участие!

S>Во-вторых, рад сообщить, что проблема таки развязалась успешно.
S>Ну и, в-третьих, если кому интересно, сообщаю: дело, действительно, заключается в работе с очередью. И беда тут в том, что при переходе из одного состояния в другое, эта самая очередь становится временно недоступна (конкретней пока ничего не могу сказать). Поэтому, чтобы все события срабатывали нормально, необходимо, чтобы после срабатывания одного события и перед перехватом другого, вся стейт-машина хоть на мгновение, но попала в состояние IDLE. Для этой цели служит аргумент WaitForIdle в классе ExternalDataEventArgs. Выставляя его в TRUE, Вы определяете, что никакое новое событие не будет рассматриваться до тех пор, пока машине не побывает в состоянии IDLE. В результате все начинает работать корректно.
S>Еще раз всем большое спасибо!

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

S>эта самая очередь становится временно недоступна (конкретней пока ничего не могу сказать)

Тут как раз все вполне понятно. Очередь создается при заходе в конкретное состояние (точнее, группа очередей, по одной для события) и уничтожается при выходе. Если в следующем состоянии есть обработчик того же события, то очередь для его обработки будет создана заново.

S>Поэтому, чтобы все события срабатывали нормально, необходимо, чтобы после срабатывания одного события и перед перехватом другого, вся стейт-машина хоть на мгновение, но попала в состояние IDLE.

Не думаю. На самом деле все проще гораздо — если вы задаете флаг, то событие попадет в workflow только тогда, когда она войдет в состояние idle, это верно. Но когда она войдет в idle? Это произойдет после того, как переход в другое состояние в результате обработки сообщения будет завершен и wokflow уснет в ожидании новых событий — предварительно создав все нужные учереди. Вот тут-то ваше отложенное событие workflow и догоняет.

Вам спасибо, я про этот флаг и не знал даже.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.