how to rotate a rectangle in another thread without create new RotateTransform in WPF?
我为实时 PPI 显示器开发了一个 WPF 应用程序。我想在 Animator Thread() 中旋转一个名为"手"的矩形。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public unsafe void Animator_Thread() { RotateTransform rotateTransform = new RotateTransform(ins_angle); while (true) { this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate() { //update hand angle rotateTransform.Angle = ins_angle ; hand.RenderTransform = rotateTransform; //hand.RenderTransform = new RotateTransform(ins_angle); //update Bitmap image1.Source = BitmapSource.Create(width, height, dpiX,dpiY,pixelFormat,myPalette,Image_Buff,stride); })); } } |
但是当我运行线程时会出现这个错误:(
The calling thread cannot access this object because a different
thread owns it.
当我使用注释行
1 | //hand.RenderTransform = new RotateTransform(ins_angle); |
而不是
1 2 | rotateTransform.Angle = ins_angle ; hand.RenderTransform = rotateTransform; |
它有效。但由于耗时,我不想在每个循环中创建新的 RotateTransform。我该如何处理这个问题?
编辑:我是 C# 编程的初学者。
我不断地从局域网接收数据。为了处理和显示这些数据,我使用多个线程,例如
#数据获取线程
#rotate PPI 指针(与时钟指针相同)并更新显示位图线程。
我在图中的不同时间计算了这个动作。我希望在不到 5 毫秒的时间内完成这些工作。但有时这一行"hand.RenderTransform = new RotateTransform(ins_angle);"一个人会花更多的时间。
最后我的问题
有什么方法可以比我更快地旋转物体吗?
有什么方法可以比我更快地创建位图吗?
谢谢。
你的问题不是很清楚。但是您既不需要循环也不需要线程来为 UI 元素的 RenderTransform 设置动画。
只需使用下面示例中的内置动画,它会以 360?°/s 的速度连续为 RotateTransform 的 Angle 属性设置动画。
1 2 3 4 5 6 7 8 9 10 11 12 | var rotateTransform = new RotateTransform(); hand.RenderTransform = rotateTransform; hand.RenderTransformOrigin = new Point(0.5, 0.5); rotateTransform.BeginAnimation( RotateTransform.AngleProperty, new DoubleAnimation { By = 360, Duration = TimeSpan.FromSeconds(1), RepeatBehavior = RepeatBehavior.Forever }); |
编辑:如果您只是在后台线程中接收到一些位置数据,您需要做的就是在 Dispatcher 操作中更新现有 RotateTransform 的
前提是RenderTransform已经包含一个RotateTransform,之前在UI线程中分配过一次:
1 | hand.Dispatcher.Invoke(() => ((RotateTransform)hand.RenderTransform).Angle = ins_angle); |
如果您想将元素动画到新位置:
1 2 3 4 5 6 | hand.Dispatcher.Invoke(() => { hand.RenderTransform.BeginAnimation( RotateTransform.AngleProperty, new DoubleAnimation(ins_angle, TimeSpan.FromSeconds(1))); }); |