并行编程:无法访问UI并行?

我正在尝试在wpf c#中创建一个函数的并行执行,它也在UI上运行操作。 但是在运行时,UI控件上的方法总是存在exception:调用线程无法访问此对象,因为不同的线程拥有它。 始终在正在运行的循环的第二个实例上调用exception,因此无法在两个并行运行的实例中操作UI?

是否可以并行访问UI?

码:

do { if (listBox_Copy.SelectedIndex < listBox_Copy.Items.Count - 1) { listBox_Copy.SelectedIndex = listBox_Copy.SelectedIndex + 1; listBox_Copy.ScrollIntoView(listBox_Copy.SelectedItem); } listBox_Copy.Focus(); huidigitem = listBox_Copy.SelectedItem as ListBoxItem; currentitemindex = listBox_Copy.SelectedIndex; currentitem = listBox_Copy.ItemContainerGenerator.ContainerFromIndex(currentitemindex) as ListBoxItem; itemgrid = FindVisualChild(currentitem); senderbutton = (Button)sender; Button playcues = itemgrid.FindName("Playbutton") as Button; cuetrigger = itemgrid.FindName("cuetrigger") as TextBlock; Jobs.Add(playcues); } while (cuetrigger.Text != "go"); Parallel.ForEach(Jobs, playcues => { play(playcues, new RoutedEventArgs()); }); } 

然后它在播放function崩溃

  private void play(object sender, System.Windows.RoutedEventArgs e) { Grid itemgrid = VisualTreeHelperExtensions.FindAncestor(playcue); 

无法从后台线程访问UI,所有更新都必须在主线程上。 您可以使用Dispatcher执行此操作

像这样的东西

  Action x = (Action)delegate { //do my UI updating }; Dispatcher.Invoke(x, new object[] { }); 

诀窍是使用IProgress来报告主线程的更新。 IProgress构造函数接受将在主线程中运行的匿名函数,从而可以更新UI。

引自https://blog.stephencleary.com/2012/02/reporting-progress-from-async-tasks.html :

 public async void StartProcessingButton_Click(object sender, EventArgs e) { // The Progress constructor captures our UI context, // so the lambda will be run on the UI thread. var progress = new Progress(percent => { textBox1.Text = percent + "%"; }); // DoProcessing is run on the thread pool. await Task.Run(() => DoProcessing(progress)); textBox1.Text = "Done!"; } public void DoProcessing(IProgress progress) { for (int i = 0; i != 100; ++i) { Thread.Sleep(100); // CPU-bound work if (progress != null) progress.Report(i); } } 

现在,一点点自我推销:)我创建了一个IEnumerable扩展来运行一个并行的事件回调,可以直接修改UI。 你可以在这看一下:

https://github.com/jotaelesalinas/csharp-forallp

希望能帮助到你!