我正在努力解决这段代码引发的问题:
private int FPS = 60;
void WebView_LoadCompleted(object sender, NavigationEventArgs e)
{
WebviewContentWorker();
}
private async void WebviewContentWorker()
{
WebViewBrush wvb = new WebViewBrush();
wvb.SetSource(WebView);
wvb.Redraw(); //we must redraw at least once before collapsing the WebView
WebView.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
while (true)
{
webViewContent.Background = wvb; //webViewContent is a canvas
await Task.Delay(1000 / FPS);
wvb.Redraw();
}
}
我在这里想要实现的是找到XAML的WebView
的解决方法,我发现它非常草率。我希望能够在它上面绘制内容,但我不能这样做,我基本上做的是重复拍摄WebView
(使用WebViewBrush
)的快照(基于{{ 1}} field)然后使用此快照设置名为“int FPS
”的画布的Background
属性。目的是在画布上显示动画,同时仍然能够在其上绘制(如果我不执行这些快速快照,画布将显示静止图像)。
现在工作正常(我成功地将任何webViewContent
事件重定向到Tapped
的内部,以便正确处理按钮/链接/ ...的点击次数,但它有点滞后。缓慢的位是WebView
我想知道如何改善线程的性能。在 wvb.Redraw()
期间,用户界面似乎是的响应,但是否则会被阻止...
非常欢迎任何意见/建议!
编辑:
以下是我为Task.Delay
调用计时的时间(我认为这是导致问题的原因,因为删除它会使应用程序响应很快):
Redraw
在输出窗口中给出了这些结果:
while (true)
{
webViewContent.Background = wvb;
await Task.Delay(1000 / FPS);
sw.Reset();
sw.Start();
wvb.Redraw();
sw.Stop();
System.Diagnostics.Debug.WriteLine(sw.Elapsed.TotalMilliseconds);
}
毕竟不是那么多......
答案 0 :(得分:9)
看起来UI在Task.Delay期间是响应的,但是否则被阻止......
是的。那正是正在发生的事情。 Task.Delay
是您提供UI线程工作的唯一机会。您的异步方法正在UI线程上执行 - 一旦“延迟”任务完成,您将最终继续等待在UI线程上执行,该线程将重绘然后再次延迟。
从根本上说,如果Redraw
方法太慢而无法每秒调用60次,则需要采用不同的方法。
理解async
不将方法放在不同的线程上非常重要 - 它只允许您异步操作。 (您的描述和标题表明您希望您的方法在任何重要时间都不使用UI线程。)
另外,正如Stephen Cleary所说,使用DispatcherTimer
是在UI线程上定期执行代码的一种更好的方法。
答案 1 :(得分:2)
Task.Delay
对于反复进行多次短暂超时并不是特别有效。你会产生很多垃圾。
我建议在这种情况下使用调度程序计时器或类似工具。