SharePoint 2007 WF: действие onWorkflowItemChanged в репликаторе. Действие: ошибка токена корреляции? - PullRequest
1 голос
/ 30 августа 2011

Я пытаюсь создать функцию последовательного рабочего процесса в Visual Studio для SharePoint 2007 / MOSS. Сложность заключается в размещении действия OnWorkflowItemChanged в Replicator / Sequence ... Я столкнулся с этим на "реальной" WF, которую я строил, и после того, как некоторое время забил мою голову, создал минималистичный тест WF для воспроизведения проблемы.

Обзор моей тестовой WF заключается в том, что она связана с настраиваемым списком с двумя настраиваемыми столбцами («Первый» и «Второй», обе из одной строки текста). WF запускается при добавлении элемента и зацикливается / ждет, пока не обновится первое поле. Затем он зацикливается / ждет, пока обновится второе поле, и затем завершается.

Мой макет рабочего процесса выглядит следующим образом:

Workflow layout (v1)

Примечания:

  • replicatorActivity1 имеет тип выполнения, установленный в последовательность
  • onWorkflowActivation1 и onWorkflowItemChanged1 оба используют один и тот же токен корреляции, родительским элементом которого является Workflow (Workflow1)
  • whileActivity1 имеет свое Условие, установленное как Условие кода (полагал, что так будет проще показать)

Код этого довольно прост, но для полноты вот он:

public sealed partial class Workflow1 : SequentialWorkflowActivity {

    #region auto-created by VS
    public Workflow1() {
        InitializeComponent();
    }

    public Guid workflowId = default(System.Guid);
    public SPWorkflowActivationProperties workflowProperties = new SPWorkflowActivationProperties();
    #endregion

    // used to exit while loop
    public Boolean currentTaskDone = false;


    // when WF starts, just log to the WF history
    private void onWorkflowActivated1_Invoked(object sender, ExternalDataEventArgs e) {
        WorkflowHistory.writeSuccess(this.workflowProperties.Web, this.workflowId, "Workflow started.");
    }


    // initialize the replicator with 2 items
    private void replicatorActivity1_Initialized(object sender, EventArgs e) {
        this.replicatorActivity1.InitialChildData = new List<String>();
        this.replicatorActivity1.InitialChildData.Add("First");
        this.replicatorActivity1.InitialChildData.Add("Second");
    }


    // stop looping once this.currentTaskDone is true (written as: keep looping while false)
    private void keepLooping(object sender, ConditionalEventArgs e) {
        e.Result = !this.currentTaskDone;
    }


    // Whenever the request item is changed, check if the current field we're looking for (based on which
    //      child of the Replicator we're currently in) is set, if so: exit the loop
    private void onWorkflowItemChanged1_Invoked(object sender, ExternalDataEventArgs e) {
        WorkflowHistory.writeSuccess(this.workflowProperties.Web, this.workflowId, "Workflow item changed...");

        string nameOfFieldToCheck = this.replicatorActivity1.CurrentChildData[this.replicatorActivity1.CurrentIndex].ToString();

        string fieldValue = this.workflowProperties.Item.Fields[nameOfFieldToCheck].GetFieldValueAsText(this.workflowProperties.Item[nameOfFieldToCheck]);

        this.currentTaskDone = (0 != fieldValue.Trim().Length);
    }


    // at end of loop: reset for next iteration + log position
    private void logSequenceEnd_ExecuteCode(object sender, EventArgs e) {
        this.currentTaskDone = false; 
        WorkflowHistory.writeSuccess(this.workflowProperties.Web, this.workflowId, "Exiting sequence '" + this.replicatorActivity1.CurrentChildData[this.replicatorActivity1.CurrentIndex].ToString() + "'");
    }

Примечания * * 1023 WorkflowHistory - это пользовательский статический класс, который делает именно то, о чем вы думаете, Проблема в том, что обработчик события onWorkflowItemChanged1 НИКОГДА не сработает (каждый раз, когда он делает это, он должен написать «Элемент рабочего процесса изменен ...» в список истории). Оглядываясь вокруг, я нашел очень похожую запись здесь ( Рабочий процесс SharePoint с replicatorActivity и onWorkflowItemChanged , опубликовав это как новый вопрос для пояснения примеров), который ссылается на другую аналогичную запись ( Событие OnTaskChanged вызывается внутри ListenActivity, но не OnWorkflowItemChanged ), который утверждает, что имеет ответ. Основываясь на объяснениях Яниса во втором посте, я изменил свой рабочий процесс, как показано ниже (добавил действие intializeWorkflow1): Workflow layout (v2) Примечания

  • Без изменений кода (без обработчика initializeWorkflow1)
  • initializeWorkflow1 и onWorkflowItemChanged1 теперь используют новый токен корреляции, в то время как onWorkflowActivation1 продолжает использовать исходный токен, связанный с Workflow1

Сначала у меня был токен корреляции для intializeWorkflow1 и onWorkflowItemChanged1, присоединенный к sequenceActivity1, но затем обработчик сработал только один раз для моего элемента. Поэтому я переключил его на replicatorActivity1, и теперь WF умирает, когда он должен нажать на initializeWorkflow1 во второй раз (после первого запуска logSequenceEnd) со следующими данными в журналах ULS:

System.InvalidOperationException: Correlation value on declaration "taskToken" is already initialized.

Кто-нибудь знает способ обойти это? Это выглядит так просто ...

Редактировать 2011-08-31 9:50 (EDT) (результаты тестирования)

Одна вещь, которую я забыл упомянуть, это то, что в некоторых конфигурациях я получаю Предупреждения компилятора, когда я строю свою функцию в VS. Вот разбивка не только комбинаций и ошибок, как уже объяснено выше, но также и этих предупреждений (извините, теги TABLE не допускаются):

В то время как N-
  • Использование initializeWorkflow? Нет
  • "Внутренний токен" * активность владельца: whileActivity1
  • Предупреждение компилятора: Предупреждение проверки активности «onWorkflowItemChanged1»: корреляция может быть неинициализирована.
  • WF Результат выполнения: Обработчик НИКОГДА не срабатывает
N-Seq
  • Использование initializeWorkflow? Нет
  • "Внутренний токен" * активность владельца: sequenceActivity1
  • Предупреждение компилятора: Предупреждение проверки 'Activity' onWorkflowItemChanged1 ': корреляция может быть неинициализирована.
  • WF Результат выполнения: Обработчик НИКОГДА не срабатывает
N-Rep
  • Использование initializeWorkflow? Нет
  • "Внутренний токен" * активность владельца: replicatorActivity1
  • Предупреждение компилятора: Предупреждение проверки 'Activity' onWorkflowItemChanged1 ': корреляция может быть неинициализирована.
  • WF Результат выполнения: Обработчик НИКОГДА не срабатывает
N-WF
  • Использование initializeWorkflow? Нет
  • "Внутренний токен" * активность владельца: workflow1
  • Предупреждения компилятора:
    • Предупреждение проверки действия "onWorkflowItemChanged1": ссылочная переменная CorrelationToken 'taskToken' должна быть объявлена ​​в родительской операции нескольких экземпляров 'replicatorActivity1'.
    • Предупреждение о проверке действия onWorkflowItemChanged1: корреляция может быть неинициализирована. должен быть объявлен в родительском множественном действии 'replicatorActivity1'.
  • WF Результат выполнения: Обработчик НИКОГДА не срабатывает
Y-Seq
  • Использование initializeWorkflow? Да
  • "Внутренний токен" * активность владельца: sequenceActivity1
  • Предупреждение компилятора: Нет
  • WF Результат выполнения: Обработчик срабатывает правильно один раз, никогда больше. Нет ошибок.
Y-Rep
  • Использование initializeWorkflow? Да
  • "Внутренний токен" * активность владельца: replicatorActivity1
  • Предупреждение компилятора: Нет
  • WF Runtime result: Обработчик срабатывает корректно один раз, а затем сразу выдает ошибки.
Y-WF
  • Использование initializeWorkflow? Да
  • "Внутренний токен" * активность владельца: workflow1
  • Предупреждения компилятора:
    • Предупреждение проверки действия 'initializeWorkflow1': ссылочная переменная CorrelationToken 'loopToken' должен быть объявлен в родительском множественном действии 'replicatorActivity1'.
    • Предупреждение проверки активности "onWorkflowItemChanged1": ссылочная переменная CorrelationToken 'loopToken' должен быть объявлен в родительском множественном действии 'replicatorActivity1'.
  • WF Runtime result: Обработчик корректно срабатывает один раз, а затем сразу выдает ошибки.

* «Внутренний токен» - это тот, который используется onWorkflowItemChanged и (если он существует) initializeWorkflow

Ответы [ 2 ]

0 голосов
/ 01 сентября 2011

Я до сих пор не получил работу onWorkflowItemChanged внутри действия Replicator, но я начинаю думать, что это либо ошибка, либо намеренное ограничение дизайна (чтобы избежать путаницы при использовании Replicator в параллельном режиме).

Я решил свое конкретное решение, полностью заменив действие «Репликатор» другим действием «Пока» и переместив коллекцию дочерних данных «Репликатора» в класс WF. Это работает только для последовательного рабочего процесса, но работает.

Если кто-нибудь знает способ сделать это с репликатором, пожалуйста, оставьте этот ответ еще ...

0 голосов
/ 30 августа 2011

Можете ли вы перечислить или использовать токены, которые вы используете?Что такое «TaskToken».Обратите внимание, что токены задач различаются.

http://philwicklund.com/blog/Pages/Task-correlation-tokens-MUST-be-different!.aspx

http://msdn.microsoft.com/en-us/library/ms475438.aspx

http://social.msdn.microsoft.com/Forums/en-US/sharepointworkflow/thread/347537b5-7710-4576-98e9-fcd7b023ff0e/

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