2016-07-22 65 views
0

我的应用程序使用WPF控件来显示来自网络摄像机的许多视频。保持UI线程响应?

摘要代码如下

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线程在显示许多摄像头视频时工作得很厉害。但我不知道如何改进它。有人可以告诉我,如何解决这个问题。

非常感谢!

+0

是它的图纸是慢?或者'服务'? –

+1

你的'DisPlayVideoThreadProc'没用,因为它的有效载荷是在UI线程中执行的。请发布'bitmapQueue [i] .Serve()'代码。 – Dennis

+2

您可以将BitmapSource创建从分派器操作移出到线程方法。通过调用'img.Freeze()'来确保BitmapSources被冻结(即跨线程可访问)。 – Clemens

回答

0

不要在一次调用中绘制所有相机。这会阻止gui线程太长。您最好调用每个相机绘制的调用。或者至少在最大4


批生产可能带来的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; 
} 

如果相机的(一起)会产生太多的图像,它会自动跳过图像。

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 
    } 
}