4

Windows Azure Web ロールでホストされている ASP.NET Web API アプリケーションを使用しています。このアプリケーションの目的は、HTTP 要求を他の Web 対応エンドポイント (Service Bus Relay など) にプロキシし、それらの応答を返すことです。

重要な (>5MB) ペイロードを含むリクエストを送信すると、アプリケーションが例外をスローすることがあります。これは、ペイロードが大きいリクエストの 20 分の 1 で発生する可能性があります。

例外の詳細: System.AggregateException: 1 つ以上のエラーが発生しました。---> System.Web.HttpException: クライアントが切断されました。
System.Web.Hosting.IIS7WorkerRequest.EndRead(IAsyncResult asyncResult) で System.Web.HttpBufferlessInputStream.EndRead(IAsyncResult asyncResult) で System.Net.Http.StreamToStreamCopy.BufferReadCallback(IAsyncResult ar) --- 内部例外スタック トレースの終了 - -- ---> (内部例外 #0) System.Web.HttpException (0x800703E3): クライアントが切断されました。System.Web.Hosting.IIS7WorkerRequest.EndRead(IAsyncResult asyncResult) で System.Web.HttpBufferlessInputStream.EndRead(IAsyncResult asyncResult) で System.Net.Http.StreamToStreamCopy.BufferReadCallback(IAsyncResult ar)<--- ; TraceSource 'w3wp.exe' イベント

これらの Http 要求は、.NET 4.5 の System.Net.HttpClient を使用して送信します。

public class ProxyController : ApiController
{
    private static readonly HttpClient HttpClient = new HttpClient();
    private static readonly Uri BaseUri = new Uri("http://webendpoint.com");

    public HttpResponseMessage Post()
    {
        var newUri = new Uri(BaseUri, Request.RequestUri.PathAndQuery);
        var request = new HttpRequestMessage(HttpMethod.Post, newUri)
                {
                    Content = this.Request.Content
                };

        var task = HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
        task.Wait();
        var response = task.Result;
        return new HttpResponseMessage(response.StatusCode)
        {
            Content = new PushStreamContent((stream, content, ctx) =>
            {
                var tempStream = response.Content.ReadAsStreamAsync().Result;
                tempStream.CopyToAsync(stream).Wait();
                stream.Flush();
                stream.Close();
            })
        };
    }
}

この問題の原因について何か考えはありますか?

4

1 に答える 1

1

タスク バージョンを返してから、同期コードを非同期に置き換えてみてください。".Results" の代わりに、"await" キーワードを使用して、メソッドに "asyc" キーワードを追加します。このようなもの:

public class ProxyController : ApiController
{
    private static readonly HttpClient HttpClient = new HttpClient();
    private static readonly Uri BaseUri = new Uri("http://webendpoint.com");

    public async Task<HttpResponseMessage> Post()
    {
        var newUri = new Uri(BaseUri, Request.RequestUri.PathAndQuery);
        var request = new HttpRequestMessage(HttpMethod.Post, newUri)
        {
            Content = Request.Content
        };

        var response = await HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);

        return new HttpResponseMessage(response.StatusCode)
        {
            Content = new PushStreamContent(async (stream, content, ctx) =>
            {
                var tempStream = await response.Content.ReadAsStreamAsync();
                await tempStream.CopyToAsync(stream);
                stream.Flush();
                stream.Close();
            })
        };
    }
}
于 2014-11-05T19:32:49.743 に答える