2

我正在努力解决这段代码引发的问题:

    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)(基于int FPS字段)拍摄快照,然后设置Background名为“的画布的属性” webViewContent“与这张快照。目的是在画布上显示动画,同时仍然能够在其上绘制(如果我不做这些快速快照,画布将显示静止图像)。

它现在工作正常(我成功地将任何Tapped事件重定向到内部,WebView以便正确处理对按钮/链接/...的点击),但它有点滞后。缓慢的一点是wvb.Redraw()我想知道如何提高线程的性能。看起来 UI在此期间是响应式的,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,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

所以毕竟没有那么多...

4

2 回答 2

8

看起来 UI 在 Task.Delay 期间是响应式的,但在其他情况下被阻止...

嗯,是。这正是正在发生的事情。Task.Delay是您让 UI 线程工作的唯一机会。您的异步方法正在 UI 线程上执行 - 一旦“延迟”任务完成,您最终将继续等待在 UI 线程上执行,该线程将重绘然后再次延迟。

从根本上说,如果您的Redraw方法太慢而无法每秒调用约 60 次,那么您需要一种不同的方法。

理解async 不要将方法放到不同的线程上是非常重要的——它只是允许你异步操作。(您的描述和标题表明您希望您的方法在任何重要时间都不会使用 UI 线程。)

此外,正如 Stephen Cleary 所说,使用 aDispatcherTimer通常是在 UI 线程上定期执行代码的更好方法。

于 2013-06-20T15:18:16.890 回答
2

Task.Delay对于重复执行许多短超时不是特别有效。你会产生很多垃圾。

我建议在这种情况下使用调度程序计时器或类似的。

于 2013-06-20T15:18:48.467 回答