Windows Workflow Runtime теряет тонну памяти - PullRequest
3 голосов
/ 12 января 2010

Вот краткий обзор моей реализации рабочего процесса:

  • Поток GUI запускает рабочий поток
  • рабочий поток анализирует некоторые данные
  • рабочий поток запускает несколько других рабочих потоков для работы с подмножествами данные
  • каждый из этих последних рабочих потоков создает среду выполнения рабочего процесса и выполняет последовательный рабочий процесс

До сих пор я создавал новый объект WorkflowRuntime в каждом потоке, например:

  using( WorkflowRuntime workflow_runtime = new WorkflowRuntime()) {
      AutoResetEvent waitHandle = new AutoResetEvent(false);
      workflow_runtime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e) {waitHandle.Set();};
      workflow_runtime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)
      {
          Console.WriteLine(e.Exception.Message);
          waitHandle.Set();
      };

      WorkflowInstance instance = workflow_runtime.CreateWorkflow(typeof(MyWorkflow), parameters);
      instance.Start();
      waitHandle.WaitOne();
}

Причина, по которой я так поступаю, заключается в том, что мне нужно знать, когда конкретный экземпляр рабочего процесса был прерван или ошибочен. Проблема в том, что это вызывает огромную утечку памяти в моем приложении, как упоминалось здесь, на SO .

Если я использую ключевое слово using или даже вызываю Dispose и устанавливаю для ссылки workflow_runtime значение null, я получаю значительную утечку памяти. Однако, если я реализую среду выполнения рабочего процесса как Singleton, , как описано в этом посте , использование памяти будет очень низким и непротиворечивым. Я вижу, когда рабочие процессы запускаются и завершаются по графику на графике.

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

РЕДАКТИРОВАТЬ: я должен просто использовать другой дескриптор в стеке для ошибок, а затем ждать, пока будет установлен любой из них, а затем проверить, какой из них был установлен? Я должен был подумать об этом раньше.

1 Ответ

2 голосов
/ 13 января 2010

Итак, вот как я решил решить проблему. Если с моим решением что-то не так, пожалуйста, оставьте комментарии, и я отмечу чужой ответ, если он правильный.

Я изменил код, чтобы отменить регистрацию обработчиков событий в моем предыдущем посте, и подтвердил, что код выполняется, установив точки останова. После запуска приложения оно все равно утекло 1,5 ГБ.

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

Я реализовал шаблон Singleton из http://bit.ly/8pkEWT и, кроме того, отменил регистрацию обработчиков событий и обработал идентификаторы InstanceID. Утечка памяти исчезла! Тем не менее, я не удосужился проверить результаты каждого рабочего процесса. (Yikes)

...