2012-04-02 15 views
0

ワークフローを呼び出す以下のコードがあります。 async ctpを使用してコントローラを非同期に変更できるかどうか疑問に思っています。非同期ctp MVC4とワークフロー

public ActionResult Index() 
    { 
     var input = new Dictionary<string, object>(); 
     input["ViewData"] = this.ViewData; 
     var userState = "BeginInvoke example"; 

     var invoker = new WorkflowInvoker(HelloMvcDefinition); 

     Task workflowTask = Task.Factory.FromAsync<IDictionary<string, object>>(
      invoker.BeginInvoke(input, WorkflowCompletedCallback, userState), 
      invoker.EndInvoke); 

     workflowTask.Wait(); 

     return View(); 
    } 

私はこれを試してみましたが、私はそれを動作させるように見えることはできません。

public async Task<ActionResult> Index() 
    { 
     var input = new Dictionary<string, object>(); 
     input["ViewData"] = this.ViewData; 
     var userState = "BeginInvoke example"; 

     var invoker = new WorkflowInvoker(HelloMvcDefinition); 

     Task workflowTask = Task.Factory.FromAsync<IDictionary<string, object>>(
      invoker.BeginInvoke(input, WorkflowCompletedCallback, userState), 
      invoker.EndInvoke); 

     await workflowTask; 

     return View(); 
    } 

残念ながらビューが動作するようには思えません。私が間違っていることに関するアイデアは?

EDIT アドバイスを受けた後、私はこの問題は、私は非同期キーワードを使用していますどのようにする必要がありので、正常に動作します。この

public class HelloController : AsyncController 
{ 
    private static readonly HelloWorkflow HelloMvcDefinition = new HelloWorkflow(); 

    public Task<ViewResult> Index() 
    { 
     var input = new Dictionary<string, object>(); 
     input["ViewData"] = ViewData; 
     const string userState = "BeginInvoke example"; 

     var invoker = new WorkflowInvoker(HelloMvcDefinition); 

     return Task.Factory.FromAsync<IDictionary<string, object>>(
      invoker.BeginInvoke(input, WorkflowCompletedCallback, userState), 
      invoker.EndInvoke).ContinueWith(t => View()); 
    }  

    static void WorkflowCompletedCallback(IAsyncResult result) 
    { 

    } 
} 

に方法を変更しました。

おかげ

+0

症状をさらに説明できますか?また、待っているだけを.Wait()に変更すると(非同期とマークされたままになります)、再び動作しますか?ありがとう –

+0

問題は、非同期キーワードを使用していると思われます。私がWait()を追加すると、それはまだ動作しません。このコントローラーを呼び出すと、ワークフローのメッセージが表示された状態でビューが表示されますが、現在のところブラウザーは回転し続けています。 – Beats

答えて

0

AsyncController代わりのControllerから派生します。

EDIT:あなたはまた、アクションが完了Taskを返す場合ASP.NET MVC4がハングしますknown bugを経験することができます。このバグを回避するには、アクションメソッドの上部にawait Task.Yield();を追加します。無関係なノートで

、このコードは(あまりにも、短い)より効率的である:

var workflowTask = Task.Factory.FromAsync(invoker.BeginInvoke, invoker.EndInvoke, 
    input, userState); 
+0

応答していただきありがとうございますが、残念ながらこれが実行されても変更はありません。 – Beats

+0

私の更新された回答を参照してください。 –

+0

ありがとうございますが、2つのことがあります。 1、task.Yield()をTaskEx.Yield()に変更しましたか? 2、短いコードはコンパイルさえしません。 – Beats

1

我々は次のように窓のワークフローを呼び出すためのTAPパターンを使用することができます - (詳細は私のブログの記事に記載されていますhttp://tweetycodingxp.blogspot.com/2013/06/invoke-workflow-wf-using-task-based.html

public async Task<ActionResult> Index(string id) 
{ 
    var wfInputArgs = new Dictionary<string, object> 
    { 
     ... 
    }; 

    var wfOutputArgs = await Task<IDictionary<string, object>>.Factory.StartNew(
     () => WorkflowInvoker.Invoke(new MyWorkflow(), wfInputArgs)); 
    var result = wfOutputArgs["Output1"] as IEnumerable<Class1>; 
    ... 
    return View(model); 
} 
関連する問題