c# 如何异步更新列表框?
Posted
技术标签:
【中文标题】c# 如何异步更新列表框?【英文标题】:How to update a listbox asyncronously c#? 【发布时间】:2021-08-27 08:35:33 【问题描述】:您好,我正在尝试异步更新我的列表框,因此更新时它不会冻结一秒钟,不幸的是它会引发异常
我的代码
private async void timer1_Tick(object sender, EventArgs e)
await Task.Run(() =>
listBox1.DataSource = listboxitems;
listBox1.TopIndex = listBox1.Items.Count - 1;
);
例外
System.Reflection.TargetInvocationException:
InvalidOperationException: Invalid cross-thread operation: the listBox1 control was accessed by a different thread
than the thread for which it was created.
任何人都知道了,我该如何解决这个问题?
【问题讨论】:
这能回答你的问题吗? How to update a list box by an asynchronous call? 除了更新listBox1
之外,您还在await Task.Run
中执行其他操作吗?为了简单起见,您在此处删除了这些内容?
仅使用任务/线程来收集数据,然后在 UI 线程中使用BeginInvoke()
委托,或者使用标准的IProgress<T>
委托,在此处调用ListBox.BeginUpdate();
,设置数据使用DataSource 属性或Items.AddRange()
方法,然后是ListBox.EndUpdate();
Jimi - 你有这方面的例子吗(对于 AddRange)?我实际上遇到了同样的问题,但是有一个列表视图,这里的答案不完整,并且没有用于 winforms 列表视图的数据源属性(可能是因为它需要项目和子项目)
【参考方案1】:
跨线程是当您尝试从另一个线程(在您的情况下为任务)调用主线程的方法(在您的情况下为 UI 方法)时。
您可以从辅助线程询问该 UI 线程执行如下工作:
listBox1.Dispatcher.Invoke(() =>
listBox1.DataSource = listboxitems;
listBox1.TopIndex = listBox1.Items.Count - 1;
);
【讨论】:
不幸的是“找不到调度程序” 找不到调度程序?在视觉工作室或执行代码时?在任何情况下,您都可以使用 UI 线程中的每个项目:一个窗口、一个按钮......以上是关于c# 如何异步更新列表框?的主要内容,如果未能解决你的问题,请参考以下文章