WPF多線程更新UI的一個解決途徑


那么該如何解決這一問題呢?通常的做法是把耗時的函數放在線程池執行,然后切回主線程更新UI顯示。前面的updateTime函數改寫如下:

    private async void updateTime()
    {
        while (true)
        {
            await Task.Run(() => Thread.Sleep(900));
            textBlock.Text = DateTime.Now.ToString();
            await Task.Delay(100);
        }
    }

這種方式能滿足我們的大部分需求。但是,有的操作是比較耗時間的。例如,在多窗口實時監控的時候,我們就需要同時多十來個屏幕每秒鍾各進行幾十次的刷新,更新圖像這個操作必須在UI線程上進行,並且它有非常耗時間,此時又會回到最開始的卡頓的情況。

看起來這個問題無法解決,實際上,WPF只是不允許跨線程訪問程序,並非不允許多線程更新界面。我們大可以對每個視頻監控窗口單獨其一個獨立的線程,在那個線程中進行更新操作,此時就不會影響到主線程。MSDN上有篇文章介紹了詳細的操作:Multithreaded UI: HostVisual。用這種方式將原來的程序改寫如下:

 e)
    {
        ();

        (hostVisual);
        .Content = content;

        (() =>
        {
            (hostVisual);
            ();
            control.Arrange((), content.RenderSize));
            visualTarget.RootVisual = control;

            System.Windows.Threading..Run();

        }));

        thread.SetApartmentState(.STA);
        thread.IsBackground = ;
        thread.Start();
    }

    
    {
         child;

         child)
        {
            )
                );

            .child = child;
            AddVisualChild(child);
        }

         index)
        {
            ;
        }

         VisualChildrenCount
        {
             1; }
        }
    }

這個里面用來了兩個新的類:HostVisual、VisualTarget。以及自己寫的一個VisualHost。MSDN上相關的解釋,也不算難理解,這里就不多介紹了。最后,再來重構一下代碼,把在新線程中創建控件的方式改寫如下:

 e)
    {
        createChildInNewThread<);
    }

     container) 
        ()
    {
        ();

        (hostVisual);
        container.Content = content;

        (() =>
        {
            (hostVisual);

            ();
            control.Arrange((), content.RenderSize));

            visualTarget.RootVisual = control;
            System.Windows.Threading..Run();

        }));

        thread.SetApartmentState(.STA);
        thread.IsBackground = ;
        thread.Start();
    }

當然,我這個函數多了一些不必要的的限制:容器必須是ContentControl,子元素必須是UIElement。可以根據實際需要進行相關修改。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM