簡體   English   中英

保持UI線程響應能力?

[英]Keep the UI thread responsive?

我的應用程序使用WPF Control來顯示來自網絡攝像機的許多視頻。

摘要代碼如下

public void DisPlayVideoThreadProc()
{   
    while (isDisplayThreadRunning)
    {
        Global.mainWindow.Dispatcher.Invoke(new Action(delegate()
        {
            for (int i = 0; i < numOfCamera; i++)
            {
                BitmapSource img = bitmapQueue[i].Serve(); //Pop the frame from Queue
                ControlDisplay[i].DrawImage(img); //Draw this frame on ControlDisplay[i]
            }
        }));
    }
}

當攝像機數量很大(> 15個攝像機)時,我遇到了一個問題,那么UI線程與用戶的交互非常慢。

我知道在顯示許多攝像機視頻時,UI線程會很繁重。 但是我不知道如何改善它。 有人可以告訴我如何解決此問題。

非常感謝!

不要一次調用就繪制所有攝像機。 這將阻塞gui線程太長時間。 您最好根據每次相機繪制調用調用。 或至少四個批次。


您可以將Serve()方法從調用中移除,並將其存儲在字典中,並使用DispatcherTimer對其進行更新。

偽裝:

// hold the camera images.
public class CameraImage
{
    public bool Updated {get; set; }
    public BitmapSource Image {get; set; }
}

// cache
private Dictionary<int, CameraImage> _cameraCache = new Dictionary<int, CameraImage>();


// thread method to get the images.
while (isDisplayThreadRunning)
{
    for (int i = 0; i < numOfCamera; i++)
    {
        BitmapSource img = bitmapQueue[i].Serve(); //Pop the frame from Queue
        lock(_cameraCache)
        {
            CameraImage currentCameraImage;
            if(!_cameraCache.TryGetValue(i, out currentCameraImage))
            {
                _cameraCache.Add(i, currentCameraImage = new CameraImage());
            }
            currentCameraImage.Image = img;
            currentCameraImage.Updated = true;
        }
    }
}

// index cycler
private int _index;

// display timer.
public void DispatcherTimeMethod()
{
    lock(_cameraCache)
    {
        CameraImage currentCameraImage;

        if(_cameraCache.TryGetValue(_index, out currentCameraImage))
            if(currentCameraImage.Updated)
            {
                ControlDisplay[_index].DrawImage(currentCameraImage.Image);
                currentCameraImage.Updated = false;
            }
    }

    _index++;
    if(_index >= MAXCAMERAS)
        _index = 0;
}

如果相機的(全部一起)生成太多圖像,它將自動跳過圖像。

當前,您正在單個線程(UI線程)中更新所有攝像機。 這使UI線程始終凍結,即使您沒有注意到它。

我建議使用Parallel.For更新(多個)單獨線程上的相機供稿,然后使用UI調度程序更新UI上的圖像。

像這樣:

while ( isDisplayThreadRunning ) {

        //start a new parallel for loop
        Parallel.For( 0, numOfCamera, num => {
           BitmapSource img = bitmapQueue[i].Serve(); //Pop the frame from Queue

           //draw the new image on the UI thread
           Global.mainWindow.Dispatcher.Invoke(
              new Action( delegate
              {
                 ControlDisplay[i].DrawImage( img ); //Draw this frame on ControlDisplay[i]
              } ) );
        } );

        Thread.Sleep( 50 );//sleep if desired, lowers CPU usage by limiting the max framerate
     }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM