スポンサーサイト

    PAYDAY2 Blacklist Assist

    最近更新中のPAYDAY2のBlacklist MODの補助ツール
    ※特に理由が無い場合は最新バージョンを使用してください。


    ━━━━━━━━━━━━━━━━━━━━━━━━━━━

    上記の広告は1ヶ月以上更新のないブログに表示されています。
    新しい記事を書く事で広告が消せます。

    [覚書] C# 非同期処理の例外処理外エラー個所の特定

    PAYDAY2 Blacklist Assist

    最近更新中のPAYDAY2のBlacklist MODの補助ツール
    ※特に理由が無い場合は最新バージョンを使用してください。


    ━━━━━━━━━━━━━━━━━━━━━━━━━━━

    最近非同期処理を実装したプログラムを書いているのだが、非同期で例外処理をきちんとしていないとエラーがとても厄介なことになると学んだ。
    この場合のエラー個所の特定方法についての覚書。

    まず、非同期処理内で例外処理(try catch)をしていない場合に表示されるエラーについて。

    非同期処理内、例外処理なし
    タイトル「TargetInvocationExceptionはハンドルされませんでした。」
    追加情報「呼び出しのターゲットが例外をスローしました。」
    rainflow_async_error1.jpg


    非同期処理内、例外処理あり
    try{ /// }catch(Exception ex){ ex.ToString(); } とりあえず例外表示するだけ
    rainflow_async_error2.jpg


    同期処理内、例外処理なし
    タイトル「ArgumentOutOfRangeExceptionはハンドルされませんでした。」
    追加情報「インデックスが範囲を超えています。負でない値で、コレクションのサイズよりも小さくなければなりません。」
    rainflow_async_error3.jpg


    今回引っかかったのは、いろいろといじって、いじりすぎて、いざデバッグを実行したところ、”非同期処理内、例外処理なし”のエラーが表示されたが、いじった個所が多すぎてどこが問題なのかわからなかったことだ。
    とりあえず、該当しそうな箇所に try{ /// }catch(Exception ex){ ex.ToString(); } を入れてみたが”非同期処理内、例外処理なし”のエラーしか出ない。

    困ってグーグル先生に聞いたところ
    「トレースログを出力する」
    とよいらしいという情報を得た。
    が、ログを出力するコードを追加したもののログを出力する前にエラーが出ているようで追加の情報は得られなかった。
    (付け焼刃でコードを追加したので追加箇所が正確ではない可能性がある。)

    これは困ったとだめもとで
    ”非同期処理内、例外処理なし”のエラーダイアログの「例外の詳細をクリップボードに追加」を実行した。


    System.Reflection.TargetInvocationException はハンドルされませんでした。
    HResult=-2146232828
    Message=呼び出しのターゲットが例外をスローしました。
    Source=mscorlib
    StackTrace:
    場所 System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
    場所 System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
    場所 System.Delegate.DynamicInvokeImpl(Object[] args)
    場所 System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme)
    場所 System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)
    場所 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
    場所 System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme)
    場所 System.Windows.Forms.Control.InvokeMarshaledCallbacks()
    場所 System.Windows.Forms.Control.WndProc(Message& m)
    場所 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
    場所 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
    場所 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
    場所 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
    場所 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
    場所 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
    場所 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
    場所 System.Windows.Forms.Application.Run(Form mainForm)
    場所 Rainflow.Program.Main() 場所 C:\Users\xxxxxxx\Documents\Visual Studio 2015\Projects\Rainflow\Rainflow\Program.cs:行 19
    場所 System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
    場所 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
    場所 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
    場所 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
    場所 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
    場所 System.Threading.ThreadHelper.ThreadStart()
    InnerException:
    HResult=-2146233086
    Message=インデックスが範囲を超えています。負でない値で、コレクションのサイズよりも小さくなければなりません。
    パラメーター名:index
    ParamName=index
    Source=mscorlib
    StackTrace:
    場所 System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
    場所 System.Collections.Generic.List`1.get_Item(Int32 index)
    場所 Rainflow.DGV.d__3.MoveNext() 場所 C:\Users\xxxxxxx\Documents\Visual Studio 2015\Projects\Rainflow\Rainflow\Control.cs:行 316
    --- 直前に例外がスローされた場所からのスタック トレースの終わり ---
    場所 System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c.b__6_0(Object state)
    InnerException:


    Message=インデックスが範囲を超えています。負でない値で、コレクションのサイズよりも小さくなければなりません。
    この情報は大きい!そしてその下の
    場所 Rainflow.DGV.d__3.MoveNext() 場所 C:\Users\xxxxxxx\Documents\Visual Studio 2015\Projects\Rainflow\Rainflow\Control.cs:行 316
    ここが問題だそうだ。

    ということで、修正しました。
    例外処理はちゃんとしようね。
    メッセージ表示するだけでも効果あるある。
    スポンサーサイト
    上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。