20

カスタムhttpハンドラーを作成しました。これは、IHttphandlerを実装するクラスを作成することで実現しました。

そのクラスの中に、私はこのようなコードを持っています、

context.Response.Clear();
context.Response.ClearHeaders();
context.Response.AddHeader("Content-Disposition", "attachment;filename=" + attachmentFileName);
context.Response.AddHeader("Content-Length", new FileInfo(downloadFile).Length.ToString());
context.Response.ContentType = GetMimeType(attachmentFileName);
context.Response.TransmitFile(downloadFile);
context.Response.Flush();
context.Response.Close();

ときどきこのようなエラーが発生しますが、

Exception HttpException The remote host closed the connection The error code is 0x800703E3

またはこれ、

Exception HttpException The remote host closed the connection The error code is 0x80070040

どちらの場合も、スタックトレースはこれです。

at System.Web.Hosting.IIS7WorkerRequest.RaiseCommunicationError(Int32 result, Boolean throwOnDisconnect)
at System.Web.Hosting.IIS7WorkerRequest.ExplicitFlush()
at System.Web.HttpResponse.Flush(Boolean finalFlush)
at System.Web.HttpResponse.Flush()

これは本番環境で発生します。過去数日間を振り返ると、エラーが23回発生し、合計で上記のコードは497回呼び出されています。

この失敗は、ユーザーがリンクをクリックして上記のコードを複数回開始し(複数のダウンロードダイアログが表示される)、一部のコードをキャンセルしたことに関連していると思われます。そうは言っても、そのようなものであれば、両端で接続が正常に閉じることを期待していました。

このエラーの正確な原因をどのように証明できますか?このように.NETトレースを有効にしようとしました。トレースリスナーがカスタムハンドラトラフィックをログに記録しないのはなぜですか。しかし、それを機能させることができませんでした。

ただし、IISトレースを有効にして、失敗した要求をログに記録していることがわかりました。障害が再び発生し、そのログには何もありませんでした。

たとえば、他に有効にできるトレースはありますか?

次に試したのはこれでした

if (context.Response.IsClientConnected)
{
    context.Response.Flush();
    context.Response.Close();
}
else
{
    LogMessage("Client has disconnected before flush was called", Severity.Information);
}

しかし、それは何の違いもありませんでした。私が推測する理由は、フラッシュが呼び出される前ではなく、ダウンロードが行われている間にクライアントが切断されたためです。

4

7 に答える 7

14

Flush()との両方を取り出してClose()呼び出します。あなたは本当にそれらを必要としません。ハンドラーが完了すると、ハンドラーは終了し、ASP.NETが要求のクローズを処理します。

さらに、Flush()コンテンツをクライアントにストリーミングする場合(ブロック単位で応答ストリームにパーツを追加する場合)に使用する必要があります。と一緒に使用する必要はありませんTransmitFile()

于 2011-05-25T02:42:58.123 に答える
8

私は同様の問題に直面していましたが、Response.End() を避けるべきであると説明し、代わりに CompleteRequest() メソッドを使用することを提案するこの記事を入手しました。MSDN ドキュメントもこの情報で更新されています。これが誰かに役立つことを願っています。

http://blogs.msdn.com/b/aspnetue/archive/2010/05/25/response-end-response-close-and-how-customer-feedback-helps-us-improve-msdn-documentation.aspx

于 2012-03-06T21:40:28.437 に答える
4

Response.End()の代わりに使用Response.Flush()

のソースコードはResponse.End()次のようになります。

public void End()
{
    if (this._context.IsInCancellablePeriod)
    {
        InternalSecurityPermissions.ControlThread.Assert();
        Thread.CurrentThread.Abort(new HttpApplication.CancelModuleException(false));
    }
    else if (!this._flushing)
    {
        this.Flush();
        this._ended = true;
        if (this._context.ApplicationInstance != null)
        {
            this._context.ApplicationInstance.CompleteRequest();
        }
    }
}
于 2011-04-04T03:07:29.953 に答える
2

どの .NET フレームワークを使用していますか? このフォーラム スレッドは、IIS7 を .NET2.0 で使用した場合の同様の問題について説明しています。具体的には、クライアントの切断に関係しています。この問題は、.NET Framework 3.5 で対処されました。

実際のエラー コードは

0x800703E3 "The I/O operation has been aborted because of either a thread exit or an application request."
于 2011-04-03T23:02:02.003 に答える
1

Web 構成で最大サイズのファイルをより大きなものに設定してみてください。

maxRequestLength を設定できます (kb 単位)

また、iis のアプリ プールを頻繁に再利用しないようにしてください。

于 2011-04-04T01:25:21.613 に答える
1

この例外の詳細については、http://support.microsoft.com/kb/977453にアクセスしてください。

于 2012-01-10T10:03:20.607 に答える