2012-07-06 9 views
8

.NET 4.5およびASP MVC 4 RCでVisual Studio 2012 RCを使用しています。私は非同期を使用するたびにハングします。コントローラアクションメソッドは非同期を使用しますが、それ自体が非同期コントローラメソッドではありません。asyncが使用されるたびにASP.Net MVC 4コントローラがハングする

ログに記録されたエラーや例外はありませんが、ブラウザには「Waiting for www.myweb.local」と表示されます。

// Simplest possible async 
public class Waiter 
{ 
    public async Task<int> GetValue() 
    { 
     await Task.Yield(); 
     return await Task.Factory.StartNew(() => 42); 
    } 
} 

// simplest possible controller that uses the async 
public class HomeController : Controller 

    public ActionResult Index() 
    { 
     var waiter = new Waiter(); 
     var resultTask = waiter.GetValue(); 
     int result = resultTask.Result; 

     // it never gets here 
     return View(); 
    } 
} 

私はin this answerを指摘している事を行っている、そしてそれはまだ動作しません。 すなわちweb.configファイルは

<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/> 

そして非同期メソッドであるawait Task.Yield();魔法の言葉が含まれています。

.Netフレームワークのバージョンは4.5.50501です。私はIIS ExpressとIIS 6.0でこの動作を観察しました。

「2012年7月のアップデート」をVS2012に適用しようとしましたが、修正されませんでした。

This answer suggestsタスクが既に完了しているので、私はそれがそうであった場合ただし、これは動作するはずです、それを待つとそうでないとき、それはあり得ること:

public class Waiter 
{ 
    public async Task<int> GetValue() 
    { 
     await Task.Yield(); 
     return await Task.Factory.StartNew(() => 
      { 
       Thread.Sleep(1500); 
       return 42; 
      }); 
    } 
} 

人々のカップルがあることを示唆していますConfigureAwait(false)が必要ですが、このコードはどちらか動作しません:

public async Task<int> GetValue() 
    { 
     var task = new Task<int>(() => 42); 
     return await task.ConfigureAwait(false); 
    } 

ではなく、火花と、かみそりビューエンジンとに動作します。確かに他のシナリオも同様に働かせる方法があるはずですか?同期コード内で非同期タスクを使用できませんか?

public class Waiter 
{ 
    public async Task<int> GetValue() 
    { 
     return await Task.Factory.StartNew(() => 42); 
    } 
} 

public class HomeController : Controller 
{ 
    public async Task<ActionResult> IndexAsync() 
    { 
     await Task.Yield(); 
     var waiter = new Waiter(); 
     int result = await waiter.GetValue(); 

     return View(); 
    } 
} 

私は、これはソフトウェアをリリースしていないですけど、マイクロソフト社のRCSは通常、非常に安定しているので、私はそれが失敗し、役に立たない方法で失敗したことを驚いています。

+2

申し訳ありませんが、私は何かが不足していますが、非同期にマークし、そこにawaitを使用する代わりに、インデックスプロパティブロックにResultプロパティを使用してアクセスします。これが意図的な場合は、ConfigureAwait(false)を使用して継続が同じスレッドでスケジュールされないようにする必要があります。 –

+0

私は、既存のWebサイトを.Net 4.5に移植することをテストしています。スパークビューエンジンを使用します。私は非同期コントローラを扱う前に非同期作業をしたいと思っていましたし、SparkがTask を処理できるかどうか(私の最初の印象はnoでした)。しかし、それができるかどうかに関係なく、このシナリオはうまくいくはずです。 – Anthony

+0

なぜAsyncControllerから派生していますか?それは必要ではありません。私の非同期のサンプルを参照してください。http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4 – RickAndMSFT

答えて

1

私はベータ版で非同期で作業しています。私はそれをテストしていないが、あなたのコントローラメソッドが非同期ではないためだと思います。

public async Task<ActionResult> IndexAsync() 
{ 
    var waiter = new Waiter(); 
    int result = await waiter.GetValue(); 

    // it never gets here 
    return View(); 
} 
+0

「コントローラメソッドが非同期ではないため」の場合は、非同期タスクを使用すると同期コードで動作しないと言っていますか?さもなければ、このコードを働かせる方法があるはずです。 – Anthony

+0

OK、編集中にというタスクを追加しています... –

+0

GetValue()が完了していないので...私の頭の上から離れていることは、私は今電車に乗っている!誰も私に殴られなければ、後で見ていきます。 –

9

デッドロックの原因となっているのは、just like this questionです。

ジェームズ・マニングの提案は正しいですが、あなたはこのように、awaitConfigureAwaitの結果を持っている:あなたは本当に本当に悪いアイデア知っているされていない限り、同期および非同期コードとを混合し、一般的に

public async Task<int> GetValue() 
{ 
    var task = new Task<int> (() => 42); 
    return await task.ConfigureAwait(false); 
} 

、何」やっている。コントローラの動作を非同期にする方がはるかに優れています。

+1

私は同意します - コントローラメソッドを非同期にするのはとても簡単です。同期ハンドラ内でいくつかのタスクを並行して実行することが理にかなっている(非常に*非常にまれな)ケースがいくつかありますが、常に非同期コントローラで逃げる前に、この記事を読む価値があります。http://blog.stevensanderson.com/2010/01/25/measuring-the-performance-of-asynchronous-controllers/ –

+0

確かにC#プログラム非同期キーワード "同期と非同期のコードを混在させる"を使用しますか?非同期コントローラを使用すると、境界がフレームワーク内にあることを意味します。 – Anthony

+0

「コントローラのメソッドを非同期にするのはとても簡単です」に関しては、スパークビューエンジンを使用して多くの既存のビューを持っているのではなく、 – Anthony

関連する問題