2016-07-22 93 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 
    } 
}