Управление жизненным циклом рабочего процесса без «службы персистентности» - PullRequest
1 голос
/ 11 февраля 2010

Я использую Windows WF прямо сейчас для простого способа определения состояния машин. На самом деле, я даже не использую конечный автомат, я использую последовательный рабочий процесс. Со временем я откажусь от WF в пользу чего-то другого, но так как у меня уже есть работающий код, мне нужно, чтобы работали методы Abort, Suspend и Resume.

Мое приложение порождает поток, который затем порождает другой поток, которому принадлежит WorkflowInstance. В моем графическом интерфейсе есть кнопки «Прервать», «Пауза» и «Возобновить», которые в конечном итоге вызывают методы «Прервать», «Приостановить» и «Возобновить» в WorkflowInstance соответственно.

Проблема в том, что когда я делаю это, я получаю очень большой и страшный MessageBox, который говорит:

В среде размещения рабочего процесса нет службы персистентности, как требуется для операции с экземпляром рабочего процесса

вместе с хорошей трассировкой стека и все. Теперь я посмотрел эти методы в Pro WF Брюса Буковича , и один из его примеров называет эти методы, и нигде не упоминалось о «службе персистентности». Однако его примеры вызовов были в рамках WorkflowRuntime, то есть он вызывает их так:

using(WorkflowRuntimeManager manager = new WorkflowRuntimeManager(new WorkflowRuntime("WorkflowRuntime")))
{
  manager.WorkflowRuntime.StartRuntime();
  WorkflowInstanceWrapper instance = manager.StartWorkflow(typeof(SharedWorkflows.Workflow1), null);
  instance.Suspend("Manually suspended");
  instance.Resume();
  waitHandle.WaitOne();
}

В своем приложении я реализовал WorkflowRuntime как одиночный, потому что обнаружил, что при создании WorkflowRuntime, как этот, произошла огромная утечка памяти. Итак, мой код выглядит так:

WorkflowInstance instance = WorkflowRuntimeSingleton.Instance.workflow_runtime.CreateWorkflow(typeof(SharedWorkflows.Workflow1), null);
instance.Start();
instance.Suspend("Manually suspended");
instance.Resume();
waitHandle.WaitOne();

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

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

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

  1. WF-запросы на прерывание / паузу / возобновление через интерфейс с графическим интерфейсом (кажется, очень неубедительным)
  2. Замените WaitOne () на WaitAny (), и вызовите графический интерфейс объекта, которому принадлежит рабочий процесс, установите AutoResetEvent. WaitAny () позволяет продолжить выполнение, а затем мой код может проверить, какую кнопку нажал пользователь. Это нужно будет заключить в цикл, чтобы мы могли снова подождать, пока пользователь не нажмет кнопку «Прервать», или пока WF не будет завершен.
  3. использовать логический флаг, чтобы в основном делать то, что делает # 2.
  4. посмотрим, знает ли кто-нибудь на SO, как волшебным образом сделать вызов в правом потоке:)

Любое понимание или мнения будут очень признательны!

Ответы [ 3 ]

5 голосов
/ 15 февраля 2010

Создание базы данных постоянства не так уж и сложно. На самом деле, это поможет вам решить проблемы с памятью, потому что сохраняет рабочие процессы, которые приостановлены на более длительный период времени (из памяти их) Вот ссылка, которая поможет вам создать базу данных и использовать ее в своем рабочем процессе: http://msdn.microsoft.com/en-us/library/ms735722(VS.85).aspx

В ссылке упоминается изменение вашего app.config. Я этого не делал. Вместо этого я добавил сервис в коде. Как это:

//Add the persistence service
WorkflowPersistenceService persistenceService = new SqlWorkflowPersistenceService(
    DBConnections.PersistenceService,
    true,
    TimeSpan.MaxValue,
    new TimeSpan(0, 0, 15));
m_WorkflowRuntime.AddService(persistenceService);

РЕДАКТИРОВАТЬ: Еще одна полезная ссылка

1 голос
/ 20 февраля 2010

SQL Server Compact не будет работать, потому что CE не поддерживает хранимые процедуры, которые являются частью сценария создания постоянных БД по умолчанию и вызываются службой сохранения SQL. CE предназначен для встраивания двигателя в приложение. Файл БД будет использоваться с чем-то вроде SQL Server Express, где механизм запускается в отдельном процессе, но вы можете указать файл DBF, а не подключаться к БД, уже подключенной к модулю.

Судя по вашему вопросу / ответу, вы не ожидаете, что рабочий процесс, созданный одним экземпляром приложения, будет вызван другим экземпляром (общие рабочие процессы). Еще одна возможность - не использовать SQL-версию службы персистентности. Существует пример (может быть не полный, не уверенный) службы персистентности рабочего процесса, основанный на прямой сериализации рабочего процесса в файл на http://msdn.microsoft.com/en-us/library/ms741725.aspx.. Не знаю, поддерживает ли он все ваши потребности, но поскольку он включает в себя источник, вы можете настроить его.

0 голосов
/ 17 февраля 2010

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

Во всех ссылках упоминается создание базы данных с использованием Microsoft SQL Server Query Analyzer, которого у меня нет. Вместо этого я пошел в обозреватель серверов в VS2008, щелкнув правой кнопкой мыши Соединения данных -> Создать новую базу данных SQL Server. Я использовал проверку подлинности Windows и выбрал свой компьютер из списка серверов.

Я хочу иметь возможность запускать этот код на нескольких системах, используя один и тот же файл базы данных. Почему я не могу указать localhost здесь?

Что касается вышеуказанного вопроса, если я вместо этого создаю новую базу данных, используя Data Connections -> Add Connection, я могу создать файл локальной базы данных, который я могу включить в свое решение, и предположительно перенести с ПК на ПК. Это, вероятно, правильный путь, но

В чем основное различие между использованием «Microsoft SQL Server Compact 3.5» и «Файл базы данных Microsoft SQL Server»? Оба позволяют мне создать файл. Мне больше нравится выбор Compact, потому что мне не нужно использовать пароль, но я не знаю, требуется ли для этого установка другого специального сервиса на другом компьютере, который не нужен для опции Database File.

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

%WINDIR%\Microsoft.NET\Framework\v3.0\Windows Workflow Foundation\SQL\<language>\SqlPersistence_Schema

Поскольку у меня нет Query Analyzer, я решил, что выполнение запроса из VS2008 должно работать достаточно хорошо. Если я копирую и вставляю SQL в окно запроса, я получаю следующее сообщение об ошибке:

Query Definitions Differ

The following errors were encountered while parsing the contents of the SQL pane:
The Set SQL construct or statement is not supported.

с последующим:

SQL Execution Error.

Executed SQL statement: -- Copyright (c) Microsoft Corporation. All rights reserved.

SET NOCOUNT ON

--
-- ROLE state_persistence_users
--
declare @localized_string_AddRole_Failed nvarchar(256)
set @localized_string_AddRole_Failed = N'Failed adding the "state_per...
Error Source: .Net SqlClient Data Provider
Error Message: Incorrect syntax near the keyword 'if'.
Incorrect syntax near 'GO'.
Incorrect syntax near the keyword 'CREATE'.
Incorrect syntax near the keyword 'IF'.
Incorrect syntax near 'GO'.
Incorrect syntax near the keyword 'CREATE'.
Incorrect syntax near the keyword 'CREATE'.
Incorrect syntax near the keyword 'DBCC'.
Incorrect syntax near ')'.

Кто-нибудь знает, как я могу попытаться создать хранилище?

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