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)
マイクロソフトの公式の解決策 (日本語のURL)
これを読んでみて、なんとなく理由がわかりました。
どうやら、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:
1 Response.Redirect ("nextpage.aspx", false);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 を使えばよいらしいです。
他の解決策としては、単純に以下の方法があります。
1 2 3 4 5 6 7 |
try { Response.Redirect("abc.html"); } catch (Exception ex) { } |
ただ、単にこれだと、Exception、例外の握り潰しなので、Exception発生時にログに書き込むなどしてもよいかもしれません。
私の場合は、元々は、PDFを表示するように以下のように書いていました。
1 |
Response.Redirect( url ); |
これだと、ThreadAbort.Exceptionが発生するので、以下のようにResponse.WriteFileを使うとExceptionは発生しなくなりました。
1 2 |
Response.ContentType = "Application/pdf"; Response.WriteFile(url); |
とりあえず、これで解決したので良しとします。
プログラミングの無料レッスン体験
約8,000名の受講生と80社以上の導入実績のあるプログラミングやWebデザインのオンラインマンツーマンレッスンCodecamp
<Codecampの特徴>
1 現役エンジニアによる指導
2オンラインでのマンツーマン形式の講義
3大手企業にも導入されている実践的なカリキュラム
↓無料体験レッスン実施中です。
コメント