13

Task内部からを返すメソッドを呼び出す必要があります

public override void OnActionExecuting(ActionExecutingContext filterContext)

このメソッドを非同期にすることはできません。次のようになります。

非同期操作がまだ保留中に、非同期モジュールまたはハンドラーが完了しました。

と呼び出すとき

 entityStorage.GetCurrentUser().Result

デッドロックが発生します。どうすればこれを回避できますか?

私はそれで遊んでいます

entityStorage.GetCurrentUser().Result.ConfigureAwait(false).GetAwaiter().GetResult();

しかし、これは機能していません。どうすればいいですか?私のソリューションはASP.NET4とAsyncTargetingPackで動作する必要がありますが、Azureに展開しているときにASP.NET4.5を使用することはできません。

4

3 に答える 3

13

デッドロックの原因については、こちらで説明していますasyncつまり、コードをブロックしないでください。ConfigureAwait(false)ライブラリasyncコードとawait結果でを使用する必要があります (Resultまたはは使用しないでくださいWait)。

更新: MVC チームがアクション フィルターのサポートを追加するために、ここで投票してください。async

于 2012-08-09T17:12:45.103 に答える
2

awaitは、コンパイラが継続を書き換えるための単なるシンタックスシュガーであるため、最も「直接的な」パスは、待機に続くコードを取得して、ContinueWith呼び出しにすることです。

だから、次のようなもの:

entityStorage.GetCurrentUser().ContinueWith(t =>
{
    // do your other stuff here
});
于 2012-08-09T17:54:10.050 に答える
1

非同期を同期に変換する必要ある場合。

public User GetCurrentUserSynch()
    {
        return Task.Run(() =>
        {
            var asyncResult = entityStorage.GetCurrentUser();
            while (!asyncResult.IsCompleted)
            {
                Application.Current.TryFindResource(new object()); // This is for WPF but you can do some other nonsense action of your choosing
            }

            return asyncResult.Result;
        }).Result;
    }

それ以外の場合は、@Stephen の回答を使用してください。

于 2014-09-29T15:37:15.750 に答える