使用多线程访问“共享”列表框。
使用多线程访问“共享”列表框。
问题很简单,我有一个GUI c#/xaml应用程序,我想在一个线程中运行GUI,而在另一个线程中运行一些方法(无限循环)。我需要从第二个线程中修改GUI(listbox)中的元素。我尝试创建全局变量和一些其他来自网络的提示,但没有一个运行良好。现在我有类似于下面的代码:\n
public delegate void InvokeDelegate(listdata Mujlist); //在全局范围内 //在窗口类中 public void UpdateList(listdata Mujlist) { mujlistbox.DataContext = Mujlist; } //在第二个线程中 object[] obj = new object[1]; obj[0] = Mujlist; mujlistbox.BeginInvoke(new InvokeDelegate(UpdateList), obj);
\n这可能可以很好地完成工作,但是我无法尝试这个,因为VS 2010找到错误:\n
Error 1 'System.Windows.Controls.ListBox' does not contain a definition for 'BeginInvoke' and no extension method 'BeginInvoke' accepting a first argument of type 'System.Windows.Controls.ListBox' could be found (are you missing a using directive or an assembly reference?) D:\..\MainWindows.xaml.cs 85 28 WPFChat
\n但是System.Windows.Forms有这个方法,所以我对此感到困惑。所以问题是如何简单地从子线程中更新“GUI线程”中的listbox?我在哪里犯了错误?是否有更好的方法来做到这一点?如何做?
多线程访问共享的listbox的问题的出现原因是在WPF中,UI元素只能在创建它们的线程上访问和更新。这意味着如果我们尝试在其他线程上访问或更新UI元素,就会引发异常。
但是,有时我们需要在后台线程上执行一些耗时的操作,并且可能需要将结果显示在UI上。这就需要解决多线程访问共享的listbox的问题。
解决这个问题的方法是使用BackGroundWorker
并在BackGroundWorker.DoWork
方法中实现长时间运行的操作。通过添加进度报告的处理程序并从进度事件中更新UI来更新UI。
在Stack Overflow网站上有一个标记答案,提供了如何使用BackGroundWorker
的示例代码和解释。你可以在这里找到详细的解答。
简而言之,解决多线程访问共享的listbox的问题的方法是使用BackGroundWorker
来执行耗时操作,并在进度事件中更新UI。这样可以避免在其他线程上访问UI元素而引发异常。
问题的出现原因是在使用WPF时,想要在多线程中访问共享的ListBox,但是ListBox类本身并没有提供BeginInvoke方法。然而,ListBox类继承自DispatcherObject类,而DispatcherObject类有一个Dispatcher属性可以用来获取Dispatcher对象。
解决方法是使用ListBox的Dispatcher属性来调用BeginInvoke方法。具体的代码如下:
mujlistbox.Dispatcher.BeginInvoke(new InvokeDelegate(UpdateList), obj);
其中,mujlistbox是要访问的ListBox对象,InvokeDelegate是一个委托,用于指定要在UI线程上执行的方法UpdateList,obj是UpdateList方法的参数。
通过使用ListBox的Dispatcher属性和BeginInvoke方法,我们可以在多线程中安全地更新共享的ListBox。这样可以避免在多线程访问ListBox时出现的线程冲突和异常。