mTreeView と呼ばれる TreeView コントロールを持つ UserControl があります。複数の異なるスレッドからデータの更新を取得できます。これらにより、TreeView が更新されます。これを行うために、次のパターンを考案しました。すべてのデータ更新イベント ハンドラーは、ロックを取得してから、InvokeRequired をチェックする必要があります。その場合は、Invoke を呼び出して作業を行います。関連するコードは次のとおりです。
public partial class TreeViewControl : UserControl
{
object mLock = new object();
void LockAndInvoke(Control c, Action a)
{
lock (mLock)
{
if (c.InvokeRequired)
{
c.Invoke(a);
}
else
{
a();
}
}
}
public void DataChanged(object sender, NewDataEventArgs e)
{
LockAndInvoke(mTreeView, () =>
{
// get the data
mTreeView.BeginUpdate();
// perform update
mTreeView.EndUpdate();
});
}
}
私の問題は、起動時に mTreeView.BeginUpdate() で InvalidOperationException が発生することがあり、mTreeView が作成されたスレッドとは異なるスレッドから更新されているということです。LockAndInvoke のコール スタックに戻ると、見よ、c.InvokeRequired は true ですが、else ブランチが取得されました。それは、else ブランチが取得された後、別のスレッドで InvokeRequired が true に設定されたかのようです。
私のアプローチに何か問題がありますか?これを防ぐために何ができますか?
編集:私の同僚は、問題はコントロールが作成されるまで InvokeRequired が false であることであると私に言ったので、これが起動時に発生する理由です。しかし、彼はそれについて何をすべきかわからない. 何か案は?