在C#winform中键入错误backgroundworker时查找

时间:2016-06-27 08:45:18

标签: c# winforms listview backgroundworker

我有以下表格,我尝试使用backgroundworker实现增量搜索。

Winform

因此,想法是用户在顶部的textbox中输入,并且对于每次击键,下面的listview都会被过滤为仅包含用户键入的字符的项目。< / p>

我最近了解了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            
    }
}

问题

当我输入textbox时,我希望listbox能够立即响应我的击键并相应地显示过滤后的数据。相反,有一个约8秒的暂停,然后我得到这个错误:

enter image description here

我认为问题是我突出的问题,但我不知道如何解决它。是backgroundworker不能用于此目的还是我在实现中遗漏了什么?

PS:我欢迎任何不同的方式来实现这一目标。也许在更有经验的程序员中有更好的解决方案?

更新

以下是我正在使用的progresschanged事件:

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

由于

3 个答案:

答案 0 :(得分:0)

如果使用UI线程创建控件,则无法通过另一个线程(例如某个后台线程)访问它

只需调用在主线程上抛出跨线程异常的块:

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

答案 1 :(得分:0)

如果要更新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);
        }
    }

答案 2 :(得分:0)

这是因为您正在尝试从您创建的另一个线程在UI线程上运行的控件,这被认为是非法的。对此的正确解决方法是调用您的控件,在本例中为ListView。

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

但是如果你想成为一个反叛者并做非法的事情(讽刺),请在你的InitializeComponents()之后添加这段代码;表单构造函数中的方法。

Control.CheckForIllegalCrossThreadCalls = false;

但不要,有一个原因称它为“非法线程调用”:)

了解更多信息Control.CheckForIllegalCrossThreadCalls Property