我有以下表格,我尝试使用backgroundworker
实现增量搜索。
因此,想法是用户在顶部的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秒的暂停,然后我得到这个错误:
我认为问题是我突出的问题,但我不知道如何解决它。是backgroundworker
不能用于此目的还是我在实现中遗漏了什么?
更新
以下是我正在使用的progresschanged
事件:
private void backgroundWorker1_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
toolStripProgressBar1.Value = e.ProgressPercentage;
tsLabelTwo.Text = e.ProgressPercentage.ToString() + @"%";
}
由于
答案 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;
但不要,有一个原因称它为“非法线程调用”:)