2011-08-03 19 views
0

私はWorkFlow 4(WF 4)の初心者ですが、MVC 3で重大な問題が発生しています。コントローラからWorkFlow 4の完了後にポップアップメッセージを表示MVC

workFlowで例外が発生した場合やoutpput引数で返されたものがある場合は、ユーザーが編集するページがあり、最後に[保存]ボタンをクリックすると、ポップアップメッセージを表示する必要があります。

[保存]ボタンをクリックすると、フォームがコントローラに送信され、ワー​​クフローが実行されます。ワークフローが完了したら、ワークフローによるデータの更新が成功したかどうかを示す出力が表示されます。私はそれを非同期的に実行するので、メソッドがユーザーに戻り、並行してワークフローがイベントを呼び出していることを意味します。

[HttpPost()] 
    public ActionResult SaveVehicles(vehiclesData model) { 
    Services.VehiclesDataUpdate vehiclesDataUpdate = new Services.VehiclesDataUpdate(this.SessionData.DealerLotKey, null, null); 
      IDictionary<string, object> parameters = new Dictionary<string, object>(); 
      parameters.Add("VehiclesDataUpdate", vehiclesDataUpdate); 
      parameters.Add("UnionVehicles", unionVehicles); 
      parameters.Add("SolrVehicles", solrVehicles); 

      IDictionary<string, object> outputs = new Dictionary<string, object>(); 
      AutoResetEvent syncEvent = new AutoResetEvent(false); 
      WorkflowApplication wfApp = new WorkflowApplication(new VehiclesUpdate(), parameters); 

      wfApp.Completed = delegate(WorkflowApplicationCompletedEventArgs e) { 
       outputs = e.Outputs; 
       syncEvent.Set(); 

       if (!errorExceptions.IsNullOrEmpty()) { 
        //TODO: Render a parital view to display an error message or the result of the workflow in the ouptput 
        //TODO: Logging. 
       } 
      }; 

      wfApp.Aborted = delegate(WorkflowApplicationAbortedEventArgs e) { 
       syncEvent.Set(); 
      }; 

      wfApp.Run(); 

return View(model); 
    } 

は、どのように私は、ユーザーのワークフロー完了に戻って何かを送ることができます:ここでは

は、コントローラ内の私のコードですか?

ありがとうございます。

+0

[WorkflowInvoker](http://msdn.microsoft.com/en-us/library/system.activities.workflowinvoker.aspx)、[ManualResetEvent](http://msdn.microsoft.com/en-us/library/system.activities.workflowinvoker.aspx) us/library/system.threading.manualresetevent.aspx)を使用して、ワークフローアプリケーションが実行を完了したことをASP.NETワーカースレッドに通知します。 – Will

+0

私に例を教えてもらえますか? –

+0

ここにはたくさんのものがあります。 [wf4]を通り越して読んでください。 ASP.NETで[非同期ページ](http://msdn.microsoft.com/en-us/magazine/cc163725.aspx)を使用すると、より良い解決策が得られると考えられるので、私は答えません。問題は、適切な答えを出すために私がこれに十分に精通しているところがどこにもないことです。 – Will

答えて

0

MVCアクションからワークフローを実行するには、いくつかの方法があります。最初は、あなたがしたようにWorkflowApplicationを使用することができます。私はWorkflowApplicationに適したAyncControllerを使用するようにコードを修正しました。

public class HomeController : AsyncController 
{ 
    [HttpPost()] 
    public void SaveVehiclesAsync(vehiclesData model) 
    { 
     Services.VehiclesDataUpdate vehiclesDataUpdate = new Services.VehiclesDataUpdate(this.SessionData.DealerLotKey, null, null); 
     IDictionary<string, object> parameters = new Dictionary<string, object>(); 
     parameters.Add("VehiclesDataUpdate", vehiclesDataUpdate); 
     parameters.Add("UnionVehicles", unionVehicles); 
     parameters.Add("SolrVehicles", solrVehicles); 

     WorkflowApplication wfApp = new WorkflowApplication(new VehiclesUpdate(), parameters); 

     wfApp.Completed = delegate(WorkflowApplicationCompletedEventArgs e) { 
      AsyncManager.Parameters["outputs"] = e.Outputs; 
      AsyncManager.OutstandingOperations.Decrement(); 
     }; 

     wfApp.Aborted = delegate(WorkflowApplicationAbortedEventArgs e) { 
      AsyncManager.OutstandingOperations.Decrement(); 
     }; 

     AsyncManager.OutstandingOperations.Increment(); 
     wfApp.Run(); 
    } 

    public ActionResult IndexCompleted(IDictionary<string, object> outputs) 
    { 
     var model = outputs["model"]; 
     return View(model); 
    } 
} 

ただし、必ずしも最適な解決策ではない場合があります。一般に、ASP.NETサーバーはすべてのコアを幸せにするほどビジー状態になるので、非同期処理はスケール機能を傷つけるだけです。あなたのワークフローが主に非同期IOを行っている場合、これは問題ありませんが、同期IOまたは処理を行っている場合は、代わりにWorkflowInvokerを使用する方が良いかもしれません。

コードは次のようなものになります。

public class HomeController : Controller 
{ 
    [HttpPost()] 
    public ActionResult SaveVehicles(vehiclesData model) 
    { 
     Services.VehiclesDataUpdate vehiclesDataUpdate = new Services.VehiclesDataUpdate(this.SessionData.DealerLotKey, null, null); 
     IDictionary<string, object> parameters = new Dictionary<string, object>(); 
     parameters.Add("VehiclesDataUpdate", vehiclesDataUpdate); 
     parameters.Add("UnionVehicles", unionVehicles); 
     parameters.Add("SolrVehicles", solrVehicles); 

     IDictionary<string, object> outputs = WorkflowInvoker.Invoke(new VehiclesUpdate(), parameters); 

     var model = outputs["model"]; 
     return View(model); 
    } 
} 

注:Notepad ++だけのコードは、小さな構文エラーに気付いていましたか?

+0

@Mautice:まず、答えに感謝し、多くのことについて私の目を開いた。私は非同期の方法をやっている。私は今どのように動作するのか分かっているが、SaveVehiclesAsync()はvoidメソッドではない何かを返す、私の場合、私はワークフローが処理されている間に何かをユーザに返したい、そして、ワークフローが完了したときに、私はユーザに別のものを返すでしょう。ワークフローが完了する前に、例えばSaveVehiclesAsync()を実装してビューを返すことができます。 –

+0

サーバープロセスがまだアクティブな間にブラウザに更新を送信する方法については、[this](http://encosia.com/easy-incremental-status-updates-for-long-requests/)の記事をご覧ください。 – Maurice

+0

もう一つ、このワークフローは非同期で独立して実行されるべきではありません。ワークフローが完了するまでに時間がかかり、別のページに移動しようとすると、ワークフローが完了するまで移動しません。 –

関連する問題