[解決済み] ASP.NET Web API ブラウザがリクエストをキャンセルすると OperationCanceledException が発生する。
質問
ユーザーがページを読み込むと、ASP.NET Web API 2コントローラに一つまたは複数のajaxリクエストが送られます。ユーザーが別のページに移動した場合、これらの ajax 要求が完了する前に、要求はブラウザによってキャンセルされます。ELMAH HttpModuleは、キャンセルされた各リクエストに対して2つのエラーをログに記録します。
エラー1:
System.Threading.Tasks.TaskCanceledException: A task was canceled.
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext()
エラー2です。
System.OperationCanceledException: The operation was canceled.
at System.Threading.CancellationToken.ThrowIfCancellationRequested()
at System.Web.Http.WebHost.HttpControllerHandler.<WriteBufferedResponseContentAsync>d__1b.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.WebHost.HttpControllerHandler.<CopyResponseAsync>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.WebHost.HttpControllerHandler.<ProcessRequestAsyncCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.TaskAsyncHelper.EndTask(IAsyncResult ar)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
スタックトレースを見ると、ここから例外が投げられていることがわかります。 https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Http.WebHost/HttpControllerHandler.cs#L413
私の質問は、これらの例外をどのように処理し、無視することができるかということです。
ユーザーコードの外にあるように見えますが...。
メモです。
- ASP.NET Web API 2 を使用しています。
- Web API のエンドポイントには、非同期メソッドと非同期メソッドが混在しています。
-
エラーログをどこに追加しても、ユーザーコードで例外をキャッチできない。
-
グローバル.asax
Applicaiton_Error
-
TaskScheduler.UnobservedTaskException
-
ELMAH エラー・フィルタリング
void ErrorLog_Filtering
( https://code.google.com/p/elmah/wiki/ErrorFiltering )
-
グローバル.asax
どのように解決するのですか?
これは ASP.NET Web API 2 のバグで、残念ながら、必ず成功する回避策はないと思います。私たちは バグ を提出して、私たちの側で修正することにしました。
最終的には、この場合、キャンセルされたタスクを ASP.NET に返すことが問題で、ASP.NET はキャンセルされたタスクを処理されない例外のように扱います (アプリケーション イベント ログに問題を記録します)。
その間に、以下のコードのようなものを試すことができます。これは、キャンセル トークンが発生したときにコンテンツを削除するトップレベルのメッセージ ハンドラーを追加します。レスポンスにコンテンツがない場合、バグはトリガーされないはずです。メッセージハンドラがキャンセルトークンをチェックした直後に、上位の Web API コードが同じチェックをする前にクライアントが切断される可能性があるからです。しかし、私は、ほとんどの場合において、それが役に立つと思います。
David
config.MessageHandlers.Add(new CancelledTaskBugWorkaroundMessageHandler());
class CancelledTaskBugWorkaroundMessageHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
HttpResponseMessage response = await base.SendAsync(request, cancellationToken);
// Try to suppress response content when the cancellation token has fired; ASP.NET will log to the Application event log if there's content in this case.
if (cancellationToken.IsCancellationRequested)
{
return new HttpResponseMessage(HttpStatusCode.InternalServerError);
}
return response;
}
}
関連
-
NETガベージコレクション GC診断ツール dotnet-gcmon 使用方法
-
swagger uiをasp.net coreに統合する原理
-
認証プロセスの記録にjwtを使用したネット
-
[解決済み] authenticationScheme が指定されておらず、デフォルト認証とカスタム認証で DefaultChallengeScheme が見つかりませんでした。
-
[解決済み] ファイルまたはアセンブリ 'log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821' を読み込めません でした。
-
[解決済み] web.configでmaxJsonLengthの長さを無制限に設定することは可能ですか?
-
[解決済み] Server.MapPath("."), Server.MapPath("~"), Server.MapPath(@"\"), Server.MapPath("/"). この違いは何ですか?
-
[解決済み] イベントログへの書き込み時にSystem.Security.SecurityExceptionが発生する。
-
[解決済み] Server.UrlEncode vs. HttpUtility.UrlEncode
-
[解決済み] ASP.NET Web APIでのユーザー認証
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
ASP.NET Core ディペンデンシーインジェクションの詳細
-
認証プロセスの記録にjwtを使用したネット
-
ASP.NET Coreで複数のサービス実装クラスをインジェクトする方法
-
ConfigurationManagerのGetSection()メソッドです。
-
[解決済み] Razor View Page で名前空間をインポートするにはどうしたらいいですか?
-
[解決済み] IIS 500.19 with 0x80070005 The requested page cannot be accessed because the related configuration data for the page is invalid error.
-
[解決済み] ASP.NETの新しいセキュリティ脆弱性の深刻度と回避方法について教えてください。
-
[解決済み] ポストバック時に「オブジェクトの現在の状態により操作が有効でない」エラーが発生する
-
[解決済み] .Netが間違った参照アセンブリのバージョンを選択する
-
[解決済み] Razor _layout.cshtml のファイル名の先頭にアンダースコアがあるのはなぜですか?