14

単純なビューを返すだけの同期パスと、非同期に検索を行ってからビューを返す非同期パスの 2 つのパスを持つ検索アクションがあります。どちらも GET リクエストであるため、同じアクションの一部です。

問題は、アクション「localhost:XXXX/Home/Search」にアクセスすると、ページが無限に読み込まれることです。Fiddler を使用すると、リクエストが返されないことがわかります。私はそれをデバッグし、コードの最後の行に到達しましたが、やはりリクエストは完了しません。

再現を次のように簡略化しました。

public async Task<ActionResult> Search() 
{ 
    return View(); 
} 

VS11 は、コードが await なしで同期的に実行されることを警告します。これは問題ありませんが、要求は完了しません。

これは機能するはずですか?それとも、ここで何か他のことをする必要がありますか?

編集

これは、.NET 4.5 を対象とする MVC 4 です。

編集 2

コードで物事をよりよく理解する人のために、非同期アクションで同期が必要な理由は次のとおりです。

public async Task<ActionResult> Search(string query = null)
{
    if (string.IsNullOrWhiteSpace(query))
        return View(new SearchViewModel());   // never loads

    var model = await _someService.SearchAsync(query);
    return View(model);    // loads
}
4

1 に答える 1

17

これはベータ版の既知のバグです。スティーブン・トゥーブを引用するには:

簡単に言えば、.NET 4.5 ベータ版の ASP.NET MVC には既知のバグがあり、非同期メソッドが同期的に完了するとこの問題が発生するというものです。修正が利用可能になるまで、簡単な回避策は「await Task.Yield();」を追加することです。async メソッドの最初の行として、非同期で完了するように強制します。これが正しく機能するためには、.NET 4.5 で ASP.NET によって提供される新しい SynchronizationContext を使用していることも確認する必要があります。つまり、次の行があることを確認します。

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

構成ファイルの appSettings セクションにあります。

于 2012-03-09T14:39:17.370 に答える