Получить параметры метода из метода броска в C # - PullRequest
3 голосов
/ 04 декабря 2009

У меня есть неприятное исключение, которое, кажется, происходит глубоко внутри кода DataGridView.

У меня есть класс, который наследует от BindingList, который является источником данных BindingSource, который является объектом данных DataGridView.

При некоторых странных обстоятельствах я получаю исключение во время переопределенного метода 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. Если я добавляю элемент в список, возникает событие OnListChanged, в результате чего dataGridView загружает свойства привязки к базе данных из нового экземпляра T. В получателе одного свойства у меня был какой-то код, который изменил другое свойство, которое вызвало событие OnPropertyChanged для T-объекта.

Всего одна простая блокировка (this) в методе BindingList Add, как здесь: Кто-нибудь написал потокобезопасный BindingList ? решил проблему для меня. Трудно отлаживать; (

Ответы [ 2 ]

2 голосов
/ 04 декабря 2009

С первого взгляда (и второго и третьего взгляда) Люк прав, но, глядя дальше, возможно, найдется способ. Проблема использования прямого подхода через класс StackTrace не работает, просто потому, что этот класс хранит информацию стека, включая информацию о параметре, но не данные параметра.

Эти данные будут доступны в отладочной версии, а не в версии выпуска. Чтобы получить эти данные, вы можете взаимодействовать с отладчиком Visual Studio. Вы можете сделать это программно. Тем не менее, я думаю, что проще вызвать Debugger.Break() (и, возможно, проверить, подключен ли сначала отладчик), а затем выполнить анализ.

Чтобы взаимодействовать с IDE и отладчиком, вот ответ, который объясняет, как (он объясняет, как программно устанавливать точки останова, но делает это, взаимодействуя с IDE).

Чтобы найти информацию, которую вы ищете, вы можете использовать методы автоматизации, которые будут доступны, когда вы в IDE пишете макрос. Было бы проще, если бы вы могли отражать свой путь к объектам в куче, и, возможно, есть один, но это единственный работающий метод, который я мог найти до сих пор.

1 голос
/ 04 декабря 2009

К сожалению, вы не можете получить значения аргумента из трассировки стека или исключения.

Для параметра ListChangedEventArgs доступны различные свойства, которые могут помочь при отладке: ListChangedType, NewIndex, OldIndex и PropertyDescriptor.

...