3

私は Nancy/ASP.Net プロジェクトに取り組んでいます。WebRequest を使用して他の Web サービスからデータを取得しようとしましたが、要求を非同期関数に実装しました。関数から返されたタスクを待機しようとすると、無期限にブロックされるという問題が見つかりました。簡略化されたコードは次のようになります。

using System.Net;
using System.Threading.Tasks;
using Nancy;

public class TestModule : NancyModule{
    public TestModule() {
        Get["/"] = p => "Hello, world";
        Get["/async/"] = p => {
            var req = WebRequest.CreateHttp("http://localhost:13254/");

//          var responseTask = req.GetResponseAsync();  // this works!
            var responseTask = getResponse(req);   // this gets blocked!
            var waitSuccess = responseTask.Wait(10000);

            return waitSuccess ? "Yeah!" : "woooh!";
        };
    }
    async Task<HttpWebResponse> getResponse(HttpWebRequest request) {
        return (HttpWebResponse) await request.GetResponseAsync();
    }
}

コードは NancyFx を使用していますが、バニラの ASP.Net ページでも同様に発生します。localhost:13254 のサービスは正常に動作しています。リクエストの GetResponseAsync() から直接返されたタスクを使用すると、コードは正常に機能しますが、非同期メソッドでラップすると、ブロックされるだけです。

コードの何が問題なのか誰にもわかりませんか? :(同期バージョンを使用するように変更できますが、非同期機能は他のセルフホスティングサービスで機能します...したがって、可能であればここでも同じコードを使用したいと思います..

4

2 に答える 2

4

このデッドロックの動作については、ブログ最近の MSDN の記事で説明しています。

これを修正するには、ConfigureAwait(false)どこでも使用するか、同期メソッドを使用できます。理想的な解決策は、完全awaitに使用し、Waitまたはを使用しないことですが、状況によってはそれが不可能な場合があります (ナンシーがデリゲート、つまり でResult作業した場合にのみ機能します)。asyncGet["/async/"] = async p => { ... };

于 2013-06-08T16:56:18.197 に答える