[英]Smooth WPF animations on Remote Desktop to VM
所以我试图制作一个与 VSCode 和 Atom 中使用的非常相似的对接库,但是我遇到了一些问题。 基本上,首先,我需要制作一个从宽度 0 开始的框,以增加到屏幕的末尾。 我能够做到这一点:
Rectangle rectangle = new Rectangle();
myCanvas.Children.Add(rectangle);
rectangle.Width = 0;
rectangle.Height = ActualHeight;
rectangle.Fill = new SolidColorBrush(Color.FromArgb(80, 120, 120, 120));
Storyboard sb = new Storyboard();
DoubleAnimation da = new DoubleAnimation(rectangle.Width, ActualWidth, new Duration(TimeSpan.FromMilliseconds(1000)));
Storyboard.SetTargetProperty(da, new PropertyPath("(Rectangle.Width)"));
sb.Children.Add(da);
rectangle.BeginStoryboard(sb);
animation 在我的开发机器上非常流畅,但是当远程桌面进入 VM 时,animation 非常不稳定。 但是,VSCodes 和 Atoms 动画仍然相当不错。 有什么办法可以使这项工作更好吗? 谢谢。
编辑:有没有办法为 Winforms 制作平滑的 animation ?
编辑 2:所以我在这里有这个 Winforms GDI 代码示例:
private void FastTimer_Tick(object sender, EventArgs e)
{
var x = 1;
if (solidBrush == IntPtr.Zero)
{
solidBrush = CreateSolidBrush(ColorTranslator.ToWin32(Color.FromArgb(120, 120, 120)));
hDC = CreateGraphics().GetHdc();
}
index += x;
int w = x;
int h = Height;
//create memory device context
var memdc = CreateCompatibleDC(hDC);
//create bitmap
var hbitmap = CreateCompatibleBitmap(hDC, index, h);
////select bitmap in to memory device context
var holdbmp = SelectObject(memdc, hbitmap);
RECT rect = new RECT(new Rectangle(0, 0, w, h));
FillRect(memdc, ref rect, solidBrush);
AlphaBlend(hDC, index - x, 0, w, h, memdc, 0, 0, w, h, new BLENDFUNCTION(0, 0, 128, 0));
SelectObject(memdc, holdbmp);
DeleteObject(hbitmap);
DeleteDC(memdc);
}
快速定时器核心是这样的(测试中间隔为 1000):
double frequency = Stopwatch.Frequency;
long prevTicks = 0;
while (true)
{
if (!_enabled)
{
return;
}
double interval = frequency / Interval;
long ticks = Stopwatch.GetTimestamp();
if (ticks >= prevTicks + interval)
{
prevTicks = ticks;
Tick?.Invoke(this, EventArgs.Empty);
}
}
但是,远程桌面上的动画仍然不稳定。 (我知道 RD 不能使用硬件加速,但我认为 GDI 在兼容机器上是硬件加速的,但我在我的开发机器上没有看到任何 GPU 使用)关于 thatguys 的回答,我该如何让它更快?
这些问题在 WPF 中很常见,并且是由 bitmap 远程处理引起的,请参阅此Microsoft 博客。
从 NET 3.5 SP1(包括 NET 4)的发布开始,WPF 使用服务器上的软件光栅器呈现应用程序内容,然后在所有情况下将内容远程作为位图。
由于大量重绘,这对于动画至关重要。 动画通常会同时影响一大片区域,想象一下颜色渐变。 因此,应用程序的很大一部分需要作废并重新绘制。 此外,WPF 中缺乏对遮挡的支持,这也可能加剧问题。
位图由底层 RDC 堆栈高度压缩,并且仅更新更改的区域。 另请注意,WPF 当前没有有效的遮挡支持,因此例如完全隐藏在其他不透明 WPF 元素后面的动画仍将强制失效和 RDP 更新。
您可能不会在本机 Win32 或 MFC 应用程序中遇到此问题的原因是它们使用 GDI 或 GDI+ 来绘制其用户界面控件。
当应用程序使用 GDI(例如许多 Win32 和 Winforms 应用程序)时,只有 GDI 原语被远程。 在许多情况下,这可能比远程传输 WPF 应用程序更有效,因为 WPF 应用程序远程处理位图,这通常会导致比类似的基于 GDI 的应用程序通过线路发送更多内容。 附加数据可能会导致性能下降,具体取决于网络带宽以及更新的大小和频率。
Atom 和 VS Code 是基于 Electron 构建的,它基于铬,而不是 WPF,这就是远程桌面存在很大差异的原因。
在链接的博客中,您可以找到有关如何总体提高远程性能的提示。 除了考虑在远程桌面场景中禁用动画(因为无法保证客户端的带宽或延迟等因素)之外,改进动画的基本部分是:
DesiredFrameRate
以降低 animation 帧率,进而降低流量ProgressBar
、 Button
、 ComboBox
等的默认 WPF 控制模板以及您自己的所有非必要动画中删除动画来减少流量
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.