Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 并行编程:Can';无法并行访问UI?_C# - Fatal编程技术网

C# 并行编程:Can';无法并行访问UI?

C# 并行编程:Can';无法并行访问UI?,c#,C#,我试图在wpf c#中创建一个函数的并行执行,该函数也在UI上运行操作。但是,当运行UI控件上的方法时,总会出现异常:调用线程无法访问此对象,因为其他线程拥有它。异常总是在正在运行的循环的第二个实例上调用,因此不可能在两个并行运行的实例中操作UI 可以并行访问UI吗 代码: do { if(listBox\u Copy.SelectedIndex{play(playcues,newroutedeventargs());}); 然后它在播放功能时崩溃 private void play(ob

我试图在wpf c#中创建一个函数的并行执行,该函数也在UI上运行操作。但是,当运行UI控件上的方法时,总会出现异常:调用线程无法访问此对象,因为其他线程拥有它。异常总是在正在运行的循环的第二个实例上调用,因此不可能在两个并行运行的实例中操作UI

可以并行访问UI吗

代码:

do
{  
if(listBox\u Copy.SelectedIndex{play(playcues,newroutedeventargs());});
然后它在播放功能时崩溃

private void play(object sender, System.Windows.RoutedEventArgs e)
{
    Grid itemgrid = VisualTreeHelperExtensions.FindAncestor<Grid>(playcue);
    ...
}
private void play(对象发送方,System.Windows.RoutedEventArgs e)
{
Grid itemgrid=VisualTreeHelperExtensions.FindAncestor(播放提示);
...
}

无法从后台线程访问UI,所有更新必须在主线程上。您可以通过使用Dispatcher来实现这一点

像这样的

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

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

引述自:

public async void StartProcessingButton\u单击(对象发送方,事件参数e)
{
//进度构造函数捕获我们的UI上下文,
//因此lambda将在UI线程上运行。
变量进度=新进度(百分比=>
{
textBox1.Text=百分比+“%”;
});
//DoProcessing在线程池上运行。
等待任务。运行(()=>DoProcessing(progress));
textBox1.Text=“完成!”;
}
公共无效数据处理(IProgress progress)
{
对于(int i=0;i!=100;++i)
{
Thread.Sleep(100);//CPU绑定的工作
如果(进度!=null)
进度报告(一);
}
}
现在,有一点自我提升:)我创建了一个
IEnumerable
扩展来运行与事件回调并行的,可以直接修改UI。您可以在此处查看:

希望有帮助

        Action x = (Action)delegate {
           //do my UI updating
        };
        Dispatcher.Invoke(x, new object[] { });
public async void StartProcessingButton_Click(object sender, EventArgs e)
{
  // The Progress<T> constructor captures our UI context,
  //  so the lambda will be run on the UI thread.
  var progress = new Progress<int>(percent =>
  {
    textBox1.Text = percent + "%";
  });

  // DoProcessing is run on the thread pool.
  await Task.Run(() => DoProcessing(progress));
  textBox1.Text = "Done!";
}

public void DoProcessing(IProgress<int> progress)
{
  for (int i = 0; i != 100; ++i)
  {
    Thread.Sleep(100); // CPU-bound work
    if (progress != null)
      progress.Report(i);
  }
}