3


1

C#でスローするメソッドからメソッドパラメーターを取得する

DataGridViewコードの奥深くで発生するように見える厄介な例外があります。

DataGridViewのDataSoureであるBindingSourceのDataSourceであるBindingListから継承するクラスがあります。

いくつかの奇妙な状況では、クラスのオーバーライドされたOnListChanged()メソッドで例外が発生します。

    protected override void OnListChanged(ListChangedEventArgs e)
    {
        base.OnListChanged(e); // <-- ArgumentOutOfRangeException
                               // ...Parametername: rowIndex
    }

スタックトレースは次のようになります。

    bei System.Windows.Forms.DataGridView.GetCellDisplayRectangle(Int32 columnIndex, Int32 rowIndex, Boolean cutOverflow)
    bei System.Windows.Forms.DataGridView.GetCellAdjustedDisplayRectangle(Int32 columnIndex, Int32 rowIndex, Boolean cutOverflow)
    bei System.Windows.Forms.DataGridView.InvalidateCellPrivate(Int32 columnIndex, Int32 rowIndex)
    bei System.Windows.Forms.DataGridView.OnCellCommonChange(Int32 columnIndex, Int32 rowIndex)
    bei System.Windows.Forms.DataGridView.DataGridViewDataConnection.ProcessListChanged(ListChangedEventArgs e)
    bei System.Windows.Forms.DataGridView.DataGridViewDataConnection.currencyManager_ListChanged(Object sender, ListChangedEventArgs e)
    bei System.Windows.Forms.CurrencyManager.OnListChanged(ListChangedEventArgs e)
    bei System.Windows.Forms.CurrencyManager.List_ListChanged(Object sender, ListChangedEventArgs e)
    bei System.Windows.Forms.BindingSource.OnListChanged(ListChangedEventArgs e)
    bei System.Windows.Forms.BindingSource.InnerList_ListChanged(Object sender, ListChangedEventArgs e)
    bei System.ComponentModel.ListChangedEventHandler.Invoke(Object sender, ListChangedEventArgs e)
    bei System.ComponentModel.BindingList`1.OnListChanged(ListChangedEventArgs e)
    bei My.Own.BindingList.OnListChanged(ListChangedEventArgs e)

まあ、これの周りにtry \ catch例外を追加することもできますが、なぜこれが起こるのか興味があります。

誰かが私に一度言った、私は反射とSystem.Diagnostics.StackTraceの強力な力を使用して例外を引き起こすStackFrameを取得し(これまでのところうまくいきます)、パラメータを調べます(これを行う方法がわかりません) rowindex / columnindexの値がわかっている場合は例外を追跡できます。

可能であれば、例外からパラメータを取得するように誰かに教えてもらえますか?

前もって感謝します!

更新:

この問題はいくつかのスレッドの問題に関連しているようで、rowIndexとは関係ありません。 BindingListは、DataGridViewのデータソースです。 リストにElementを追加すると、OnListChangedイベントが発生し、dataGridViewがTの新しいインスタンスからデータバインドされたプロパティをロードします。 1つのプロパティのgetterには、TインスタンスのOnPropertyChangedイベントを発生させる別のプロパティを変更するコードがありました。

次のようなBindingListのAddメソッドにある1つの単純なロック(this):https://stackoverflow.com/questions/148587/has-anyone-written-a-thread-safe-bindinglistt [スレッドセーフBindingListを作成した人はいますか? ]私のために問題を解決しました。 デバッグが難しい;(

2 Answer


2


ルークは一目見ただけでは(そして二目目と三目目も)正しいのですが、さらに目を向けると方法があるかもしれません。 StackTraceクラスを介した単純なアプローチを使用する問題は、そのクラスがパラメーター情報を含むスタック情報を保存するだけで、パラメーターデータを保存しないため、機能しません。

このデータは、リリースバージョンではなく、デバッグバージョンで使用できます。 そのデータを取得するために、Visual Studioのデバッガーと対話できます。 プログラムで行うことができます。 ただし、 `Debugger.Break()`を呼び出し(おそらくデバッガーが最初にアタッチされているかどうかを確認する)、その後分析を行う方が簡単だと思います。

IDEおよびデバッガーとやり取りするには、https://stackoverflow.com/questions/841782/programmatically-apply-deactivate-breakpoints-in-visual-studio/843130#843130 [方法を説明する回答があります](方法を説明していますプログラムでブレークポイントを設定しますが、IDEと対話することで設定します)。

必要な情報を見つけるには、IDEでマクロを作成しているときに使用できる自動化メソッドを使用できます。 ヒープ上のオブジェクトに自分の道を反映させることができれば、もっと簡単になりますが、おそらくあるかもしれませんが、これは私がこれまでに見つけた唯一の実行可能な方法です。


1


残念ながら、スタックトレースまたは例外から引数値を取得することはできません。

http://msdn.microsoft.com/en-us/library/system.componentmodel.listchangedeventargs.aspx [ListChangedEventArgs]パラメーターには、デバッグに役立つさまざまなプロパティがあります:http://msdn.microsoft。 com / en-us / library / system.componentmodel.listchangedeventargs.listchangedtype.aspx [ListChangedType]、http://msdn.microsoft.com/en-us/library/system.componentmodel.listchangedeventargs.newindex.aspx [` NewIndex`]、http://msdn.microsoft.com/en-us/library/system.componentmodel.listchangedeventargs.oldindex.aspx [OldIndex]およびhttp://msdn.microsoft.com/en-us/library /system.componentmodel.listchangedeventargs.propertydescriptor.aspx [PropertyDescriptor]。