ASP.NETで、コードが最適化されているか、またはネイティブ フレームが呼び出し履歴の最初にあるため、式を評価できません

ASP.NETで作っているプログラムで、次のようなエラーが出て来ました。

コードが最適化されているか、またはネイティブ フレームが呼び出し履歴の最初にあるため、式を評価できません

Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack

。。。さっぱり意味がわからない。

これは何でしょうか?

原因を調べてみました。

スポンサーリンク
スポンサーリンク

Response.End, Response.Redirect, Server.Transfer は ThreadAbortException を起こす

この問題調べてみたところ、以下のように原因が書かれていました。

PRB: ThreadAbortException Occurs If You Use Response.End, Response.Redirect, or Server.Transfer

現象

Symptoms
If you use the Response.End, Response.Redirect, or
Server.Transfer method, a ThreadAbortException exception occurs. You can use a try-catch statement to catch this exception.

原因

Cause

The Response.End method ends the page execution and shifts the execution to the Application_EndRequest event in the application's event pipeline. The line of code that follows Response.End is not executed.

This problem occurs in the Response.Redirect and Server.Transfer methods because both methods call Response.End internally.

マイクロソフトの公式の解決策 (英語のURL)

https://support.microsoft.com/en-us/help/312629/prb-threadabortexception-occurs-if-you-use-response-end--response-redi

マイクロソフトの公式の解決策 (日本語のURL)

https://support.microsoft.com/ja-jp/help/312629/prb-threadabortexception-occurs-if-you-use-response-end--response-redi

これを読んでみて、なんとなく理由がわかりました。

どうやら、Response.Redirect は例外を発生するようです。

私の場合は、2つのスレッドに分けて処理を行っているところで、一方で、Response.Redirectを行い、もう一方では別の処理を行うようにプログラムを書いていました。

このように、マルチスレッドのプログラムでResponse.Redirectを使うと、ThreadAbortExceptionが発生することがあるようです。

Response.End, Response.Redirect, Server.Transfer の ThreadAbortException の解決策

この問題の解決策として以下のように説明がありました。

For Response.End, call the HttpContext.Current.ApplicationInstance.CompleteRequest method instead of Response.End to bypass the code execution to the Application_EndRequest event.

Respose.End を使っている場合は、代わりに、HttpContext.Current.ApplicationInstance.CompleteRequest

を使えばよいらしいです。

For Response.Redirect, use an overload, Response.Redirect(String url, bool endResponse) that passes false for the endResponse parameter to suppress the internal call to Response.End. For example:

If you use this workaround, the code that follows Response.Redirect is executed.

Response.Redirect を使っている場合は、

Response.Redirect("nextpage.aspx", false)

を使えばよいらしいです。

For Server.Transfer, use the Server.Execute method instead.

Server.Transfer を使っている場合は、

Server.Execute を使えばよいらしいです。

他の解決策としては、単純に以下の方法があります。

ただ、単にこれだと、Exception、例外の握り潰しなので、Exception発生時にログに書き込むなどしてもよいかもしれません。

私の場合は、元々は、PDFを表示するように以下のように書いていました。

これだと、ThreadAbort.Exceptionが発生するので、以下のようにResponse.WriteFileを使うとExceptionは発生しなくなりました。

とりあえず、これで解決したので良しとします。

プログラミングの無料レッスン体験

約8,000名の受講生と80社以上の導入実績のあるプログラミングやWebデザインのオンラインマンツーマンレッスンCodecamp

<Codecampの特徴>

1 現役エンジニアによる指導

2オンラインでのマンツーマン形式の講義

3大手企業にも導入されている実践的なカリキュラム

↓無料体験レッスン実施中です。

プログラミングのオンラインスクールCodeCamp