0

ゴール:

ユーザー インターフェイスの [開始] ボタンをクリックすると、現在 2 つのバックグラウンド ワーカーが起動しています。

BGWorker 1 は .dll メソッドを呼び出して Web サイトをクロールします BGWorker 2 は Datasource = source セッターを使用して DataGridView を更新します

問題:

私の dll は引数として、.dll の実行中に設定されるデータ ソースへの参照を受け取ります。したがって、基本的に、.dll は、実行が完了するまで、時々データ ソースにオブジェクトを追加します。

BGWorker 2 はこれを行います:

while (1 == 1) // Runs until is it manually disposed
{
    CoursesGrid.BeginInvoke // inline method 
    (
        (Action) delegate 
        {
            if (_coursesSource.Count > 0) // if source is not empty,Binds.
            {
                try
                { 
                    CoursesGrid.DataSource = _coursesSource;
                    CoursesGrid.EndEdit();
                }
                catch (Exception ex)
                {
                    Logs.LogWriter.LogError(ex);
                }                   
            }
            else
            {
                // Signals User To keep Waiting
            }
        }
     );
Thread.Sleep(4000);

動作フロー:

  • DLLが呼び出されます
  • メソッド 要素を解析し、ソースに追加します
  • 最終的に、BGWorker 2 が起動し、DataGridView ソースを変更されたソースにバインドします
  • DLL スレッドは解析を続けますが、新しい要素をソースに追加しようとすると失敗します

TL:DR: スレッド 1 がソースに書き込みます スレッド 2 は、この変更されたソースを読み取り、それを DataGridView にバインドして更新します スレッド 1 ソースへの書き込みに失敗します :

"Cross-thread operation not valid: Control 'CoursesGrid' accessed from a thread other than the thread it was created on."}

両方のスレッドが同じソースを処理していますが、BGWorker 2 はそれをインターフェイスにバインドするだけで、これは機能しているはずです。ここで何が起こっているのか、何か考えはありますか?

4

1 に答える 1

2

何が起こっているのかというと、データグリッドをにバインドして_coursesSourceいるため、データグリッドに最初の行が表示されていると思います。次に、同じ _coursesSourceインスタンスを変更すると、プロパティの変更またはコレクションの変更の通知が発生し、データグリッドがそれ自体を更新しようとします(つまり、新しく追加された行が表示されます)。

ただし、変更は別のスレッドで発生しているため、データグリッドが「認識」して応答するイベントは、そのバックグラウンドスレッドでも発生し、クロススレッド違反が発生します。

あなたがする必要があるのは、a)追加を_coursesSourceUIスレッドにマーシャリングするか(簡単にできるようには聞こえない)、またはb)_coursesSourceBGWorker 2のコピーにバインドしてから、毎回BGWorker2にバインドすることです。 update_coursesSourceグリッドを新しいコピーに再バインドします。これにより、グリッドが変更通知を「聞く」ことはなく、常にコレクションの新しいコピーにバインドされます。それは物事を行うための最も効率的な方法ではありませんが、それはあなたのために仕事を成し遂げるはずです。

于 2012-06-15T20:01:49.980 に答える