まず、問題のあるコード:
public virtual void grid_RefreshFetchData(Object sender, RefreshEventArgs e)
{
C1DBGrid g = (C1DBGrid)sender;
if (g.RefreshUseResult)
{
DataTable dtNew = FetchRawData(e.Argument);
dt_Patch(dtNew, e.Argument);
g.BindingSource.SuspendBinding();
((DataTable)g.BindingSource.DataSource).Clear();
((DataTable)g.BindingSource.DataSource).Merge(dtNew);
g.BindingSource.ResumeBinding();
}
}
表示されているのは、Windowsフォームがデータを必要としているために最終的に起動されるバックグラウンドスレッドから呼び出されているイベントハンドラーです。グリッドオブジェクト(ComponentOne TrueDBGrid)はそのフォームによって所有されており、フォームがグリッドに新しいデータを要求するように指示できるようにイベントが設定されています。この呼び出しにより、このハンドラーが生成されます。このハンドラーの目的は、基になるデータクラスにレコードを含むDataTableをフェッチし、そのテーブルをグリッドのBindingSource(同じスキーマのDataTable)とマージすることです。
私の問題:新しいデータをグリッドの(新しく空になった)BindingSource(ここでもDataTable自体)にマージするためにMerge()メソッドが呼び出されると、大量の一連の例外がスローされます。各例外インスタンスは、実際には3つの例外です。1つのSystem.Reflection.TargetInvocationExceptionと、それに続く1組のSystem.InvalidOperationExceptionsです。その結果、パフォーマンスが大幅に低下します。これを修正する必要があります。
私は何が起こっているのか理解しています。フォームでは、コントロールのTextプロパティを使用して、TextBoxコントロールをグリッドのBindingSourceにバインドしています。このバインディングは、行がBindingSourceにマージされるたびに発生します。その最後の部分は観察されていません、それは少し推測ですが、例外の膨大な量はそれが正しい仮定であることを示唆しています。それと、すべてのバインディングをコメントアウトすると、パフォーマンスが劇的に向上したという事実。
したがって、私が求めているのは、このバインディングトリガーを一時停止する方法を理解するのに役立つことです。ご覧のとおり、イベントハンドラーには、BindingSourceでサスペンドしようとする行があります。
私はすでにこれも試しました:
g.SuspendBinding();
違いはありませんでした。実際、私は方程式の両端で、フォームとスレッド更新でバインディングを一時停止しようとしましたが、常にすべての試みは無益でした。
手伝ってくれますか?