[英]Why is this async method blocking the UI thread?
I am struggling with an issue which is raised by this piece of code: 我正在努力解决这段代码引发的问题:
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();
}
}
What I'm trying to achieve here is to find a workaround for XAML's WebView
which I find very sloppy. 我在这里想要实现的是为XAML的
WebView
找到一个解决方法,我发现它非常草率。 I want to be able to draw things on top of it but I can't so what I'm basically doing is taking snapshots of the WebView
(using the WebViewBrush
) repeatedly (based on the int FPS
field) and then setting the Background
property of the canvas named " webViewContent
" with this snapshot. 我希望能够在它上面绘制内容,但我不能这样做我基本上做的是重复拍摄
WebView
快照(使用WebViewBrush
)(基于int FPS
字段),然后设置Background
属性带有此快照的名为“ webViewContent
”的画布。 The aim is to have animations displayed on the canvas while still being able to draw on top of it (if I don't do these fast snapshots, the canvas will display a still image). 目的是在画布上显示动画,同时仍然可以在其上绘制(如果我不执行这些快速快照,画布将显示静止图像)。
It is working fine now (I successfully redirect any Tapped
event to the inside of the WebView
so that clicks on buttons/links/... are properly handled) but it is somehow laggy. 它现在工作正常(我成功地将任何
Tapped
事件重定向到WebView
的内部,以便正确处理按钮/链接/ ...的点击),但它有点滞后。 The slow bit being wvb.Redraw()
I was wondering how I could improve the performance of my thread. 慢点是
wvb.Redraw()
我想知道如何改善我的线程的性能。 It looks like the UI is responsive during the Task.Delay
but is blocked otherwise... 在
Task.Delay
期间看起来UI是响应的,但是否则被阻止...
Any input/advice is very welcome! 任何意见/建议都非常欢迎!
Edit: Here is how I timed the Redraw
call (which I believe is what causes the problem since removing it makes the application very responsive): 编辑:这是我如何计算
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);
}
Which gives me these results in the output window: 这在输出窗口中给出了这些结果:
0,094
0,058
0,041
0,053
0,057
0,038
0,032
0,033
0,032
0,038
0,035
0,03
0,042
0,028
0,044
0,031
0,033
0,029
0,034
0,03
0,052
0,029
So not so much after all... 毕竟不是那么多......
It looks like the UI is responsive during the Task.Delay but is blocked otherwise...
在Task.Delay期间看起来UI是响应的,但是否则被阻止...
Well yes. 嗯,是。 That's exactly what's happening.
这正是发生的事情。
Task.Delay
is the only chance you're giving the UI thread to work. Task.Delay
是你让UI线程工作的唯一机会。 Your asynchronous method is executing on the UI thread - as soon as the "delaying" task completes, you'll end up with a continuation waiting to execute on the UI thread which will redraw and then delay again. 您的异步方法正在UI线程上执行 - 一旦“延迟”任务完成,您将最终继续等待在UI线程上执行,该线程将重绘然后再次延迟。
Fundamentally, if your Redraw
method is too slow to be called ~60 times per second, you need a different approach. 从根本上说,如果您的
Redraw
方法太慢而无法每秒调用~60次,则需要采用不同的方法。
It's very important to understand that async
doesn't put the method onto a different thread - it just allows you to act asynchronously. 理解
async
不会将该方法放在不同的线程上非常重要 - 它只允许您异步操作。 (Your description and title suggest that you expected your method not to be using the UI thread for any significant time.) (您的描述和标题表明您希望您的方法在任何重要时间都不使用UI线程。)
Additionally, as Stephen Cleary says, using a DispatcherTimer
is a generally-better way of executing code periodically on the UI thread. 此外,正如Stephen Cleary所说,使用
DispatcherTimer
是在UI线程上定期执行代码的一种更好的方法。
Task.Delay
is not particularly efficient for repeatedly doing many short timeouts. Task.Delay
对于重复执行许多短暂超时并不是特别有效。 You'll generate a lot of garbage. 你会产生很多垃圾。
I would recommend using a dispatcher timer or similar for this scenario. 我建议在这种情况下使用调度程序计时器或类似计时器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.