2016-06-27 5 views
-1

私はbackgroundworkerを使用して、インクリメンタルサーチを実装しようとしています。C#winformでエラーbackgroundworkerを入力してください。

Winform

だから、アイデアは上部のtextboxにおけるユーザーの種類であり、各キーストロークのために、以下のlistviewは、ユーザが入力した文字が含まれている項目のみを含むようにフィルタリングされます。

私は最近、backgroundworkerコンポーネントについて学んだので、それを使用してフィルタリングを行い、listboxを更新しようとしていました。

これはtextboxのイベントコードである:

private void txtSearch_TextChanged(object sender, EventArgs e) 
{ 
    if (!backgroundWorker1.IsBusy) 
    { 
     backgroundWorker1.RunWorkerAsync(); 
    } 
} 

backgroundworkerイベントである:

private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) 
{ 
    if (txtSearch.Text != String.Empty) 
    { 
     GetTheListOfFiles(); 
     listView.Items.Clear(); << Exception occurs here ! 

     ...... //some more code to populate the listview control    
    } 
} 

PROBLEM

Iはtextboxに入力すると、私は期待していましたlistboxはすぐに私のキーストロークとdispに応答しますそれに応じてフィルタリングされたデータを配置する。代わりに、約8秒の一時停止があると、私はこのエラーを取得する:

enter image description here

私は、問題は、私が強調しているが、私はそれを解決する方法が分からないビットであると推定します。 backgroundworkerはこの目的のために使用できないのですか、私の実装で何かが欠けていますか?

PS:これを達成するための方法は何か歓迎します。経験豊かなプログラマーの間には、より良い解決策があるのでしょうか?

UPDATEここ

は、私が使用していますprogresschangedイベントです:

private void backgroundWorker1_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e) 
{ 
    toolStripProgressBar1.Value = e.ProgressPercentage; 
    tsLabelTwo.Text = e.ProgressPercentage.ToString() + @"%"; 
} 

おかげ

+0

可能な重複がありません:コントロール、アクセスしたが、それが作成されたスレッド以外のスレッドから](http://stackoverflow.com/questions/142003/cross-thread-operation-not-valid-control-accessed-from-a-thread-other-than-the ) – MickyD

+0

BackgroundWorkerのDoWorkイベントは、更新しようとしているUIコントロールとは異なるスレッドに存在します。これはよく知られている問題です。コントロールを更新する場合は、UIの同じスレッドで実行されるProgressChangedイベントを発生させる必要があります。 – Steve

+0

ありがとうございました。スティーブ、iveはprogresschangedイベントコードを追加しました。初心者質問:どのスレッドが実行されるのかをどのように知っていますか?歓声 – Nick

答えて

0

あなたはUIスレッドを使用してコントロールを作成する場合は、それは別のものを考えてアクセスすることはできませんスレッド(例えば、何らかのバックグラウンドスレッド)

クロススレッドexcを投げているブロックを呼び出すだけですメインスレッド上eption:

listView.BeginInvoke(new Action(() => { listView.Items.Clear(); })); 
0

あなたはUIを更新する場合は、あなたがコントロールを起動する必要があります:あなたは別のUIスレッド上で動作する制御しようとしているので

private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) 
    { 

     if (txtSearch.Text != String.Empty) 
     { 

      GetTheListOfFiles(); 
      listView.Dispatcher.BeginInvoke(new Action(() => listView.Items.Clear()), DispatcherPriority.Background); 
     } 
    } 
0

これは、あなたが作成したスレッドは違法とみなされます。これに対する正しい回避策は、コントロール(この場合はListView)を呼び出すことです。

listView.BeginInvoke(new Action(() => 
{ 
    listView.Items.Clear(); 
    //or perform your UI update or whatever. 
})); 

しかし、あなたがなりたいな反乱も、違法なもの(皮肉)を行い、(右あなたのInitializeComponents後のコードのこの部分を追加した場合)。メソッドをフォームのコンストラクタに追加します。

Control.CheckForIllegalCrossThreadCalls = false; 

しかし、より多くの情報については、それが

:)「不正なスレッドコール」と呼ばれている理由は有効ではありません[クロススレッド操作のControl.CheckForIllegalCrossThreadCalls Property

関連する問題