[英]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.