2012-03-20 2 views
1

У меня есть четко определенный контракт на обслуживание, который предоставляет кучу методов. У нас есть типичная сервисная реализация этого контракта, который размещен в IIS 7 вместе с нашим MVC-приложением.Вызов рабочего процесса WF из службы WCF

Архитектура представляет собой типичное распределенное приложение с интерфейсом, определенным в базовой библиотеке ядра (которая перераспределяется), реализация в рамках независимой библиотеки служб и, наконец, приложение MVC, отображающее конечную точку для реализации (который находится в библиотеке услуг).

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


Так что мои вопросы -

  1. Можно ли иметь независимый рабочий процесс, который может сделать это долго работает процесс и вызывать его из нашей службы WCF?
  2. Если это так, то как я могу гарантировать, что рабочий поток, выполняющий мою службу в IIS, останется в живых в течение продолжительности рабочего процесса?
  3. Наконец, клиенту не нужно ждать ответа от этой службы. Это метод огня и забывания. Может ли клиент немедленно завершить работу, пока служба запускает рабочий процесс и ждет завершения?

ответ

6
  1. Несомненно. В вашей службе WCF вы будете использовать WorkflowApplication, чтобы выполнить определение рабочего процесса. Это позаботится о том, чтобы выполнить/отслеживать каждый экземпляр WF с помощью среды выполнения WF в потоках конкретной среды WF (т. Е. Не блокировать поток ввода-вывода WCF).
  2. Здесь нет гарантий. Если пул приложений завершится с ошибкой или планируется закрыть из-за «бездействия», который завершит любые рабочие процессы, которые все еще потенциально выполняются. Вам нужно будет использовать точки сохранения, чтобы гарантировать, что если WF будет завершен, вы возобновите работу из предыдущих закладок.
  3. Да, во-первых, отметьте свой метод обслуживания WCF [OperationContract(IsOneWay=true)]. Во-вторых, вы будете использовать экземпляр WorkflowApplication с 1 для запуска WF с использованием async BeginRun, и, если вы заботитесь о завершении/ошибках отслеживания в своей службе WCF, вы можете зарегистрировать необходимые обработчики, Completed, Unloaded.

Вот очень простой пример:

[DataContract] 
public class MyParametersDataContract 
{ 
    [DataMember(Order=1, IsRequired=true)] 
    public string SomeValue 
    { 
     get; 
     set; 
    } 
} 

public class IMyService 
{ 
    [OperationContract(IsOneWay=true)] 
    void DoSomething(MyParametersDataContract someParameters); 
} 

public class MyService : IMyService 
{ 
    // Hold your WF definition in a static singleton to reduce overhead of activity realization 
    public static readonly Lazy<MyFancyWorkflow> MyWorkflow = Lazy<MyFancyWorkflow>(() => new MyFancyWorkflow()); 

    public void DoSomething(MyParametersDataContract someParameters) 
    { 
     // Example of translating incoming parameters to WF args 
     Dictionary<string, object> workflowInputArguments = new Dictionary<string, object> 
     { 
      { "SomeArgument", someParameters.SomeValue } 
     }; 

     // Create a WFA instance for this request 
     WorkflowApplication workflowApplication = new WorkflowApplication(MyService.MyWorkflow.Value, workflowInputArguments); 

     // Example of hooking the completed action 
     workflowApplication.Completed = (workflowCompletedArgs) => 
     { 
      // do something when workflow has completed 
     }; 

     // Invoke the running of the WF asynchronously 
     Task.Factory.FromAsync(
           workflowApplication.BeginRun, 
           workflowApplication.EndRun, 
           null) 
           .ContinueWith(runAntecdent => 
           { 
            // Observe/log any exception with starting the WF so it doesn't crash the process 
            Trace.TraceWarning("WF failed to run: " + runAntecedent.Exception.ToString()); 
           }, 
           TaskContinuationOptions.OnlyOnFaulted); 
    } 
} 
+0

Благодаря Дрю. Просто то, что я искал. Однако в бит «// делать что-то, когда рабочий процесс завершен», учитывая, что это служба WCF, как я могу предоставить метод обратного вызова (определенный в той же службе, возможно)? Будет ли создан новый экземпляр моей службы WCF и вызван метод обратного вызова при завершении WF? – Nikhil

+0

О да, так что если вы хотите сделать обратный вызов, вы просто захватите канал обратного вызова клиента (OperationContext.Current.GetCallbackChannel ()) в завершении обратного вызова, а затем просто вызовите метод обратного вызова. –

+0

Я собираюсь отметить это как ответ, хотя у меня не было возможности попробовать это до конца. Кажется, это сработает! – Nikhil

Смежные вопросы