我正在编写一个wpf应用程序,其中球在画布上独立弹跳,每个球在不同的线程中。每次用户点击画布时,都会向线程池添加一个新线程,并创建一个表示球的椭圆。为了添加椭圆并绘制它,我使用Dispatcher.Invoke。但是,命令myCanvas.Children.Add(el);从Invoke包围的代码中调用会导致应用程序在Invoke块结束时通过进入中断模式而崩溃。 显然,这不是实现我的目标的方式,所以我该怎么做呢?
Dispatcher.Invoke(new Action(() =>
{
Ellipse el = new Ellipse();
el.Fill = color1;
el.Margin = new Thickness(10);
el.Height = 40;
el.Width = 40;
balls.Add(ballsCounter, el);
Canvas.SetTop(el, p.Y - 2 * el.Height / 3);
Canvas.SetLeft(el, p.X - 2 * el.Width / 3);
myCanvas.Children.Add(el);
tbNumBalls.Text = ballsCounter.ToString();
}));
答案 0 :(得分:1)
您无法在一个(UI)线程上创建Ellipse
,然后将其添加到在另一个(UI)线程上创建的Canvas
。
这是不可能的,因为WPF使用具有线程亲和性的单线程执行模型。这基本上意味着不能从最初创建它的任何其他线程访问UI控件。基类中的检查通过在您尝试执行此操作时抛出InvalidOperationException
来强制执行此操作。
所以你应该在同一个线程上创建所有控件,或者让它们永远分开在不同的线程上。