2016-07-22 18 views
0

私のアプリケーションは、ネットワークカメラからの多くのビデオを表示するには、WPFコントロールを使用しています。UIスレッドは応答しますか?

要約コードは、Iカメラの量(> 15カメラ)が大きい場合は、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] 
      } 
     })); 
    } 
} 

未満です。

私は多くのカメラの映像を表示するときにUIスレッドが重い作品を知っています。しかし、私はそれを改善する方法を知らない。誰かがこの問題を解決する方法を教えてくれます。

多くの感謝!

+0

はそれが遅い描画ますか?それとも「サーブする?そのペイロードは、UIスレッドで実行されるため –

+1

あなた 'DisPlayVideoThreadProc'は、役に立たないです。 'bitmapQueue [i] .Serve()'コードを投稿してください。 – Dennis

+2

ディスパッチャアクションからBitmapSourceの作成をスレッドメソッドに移動することができます。単に 'img.Freeze()'を呼び出すことによってビットマップソースが固定されていることを確認してください。 – Clemens

答えて

0

は、すべてのカメラの1つのボークでを描画しないでください。これは、GUIスレッドを長時間ブロックします。カメラドローごとに呼び出すほうがよいでしょう。または少なくとも最大4


のバッチであなたがinvokeから出Serve()方法をもたらす可能性があり、辞書に保管し、DispatcherTimerでそれを更新します。

PSEUDO:

// 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スレッドは気付かなくても常にフリーズします。

私がお勧めすることはUI上の画像を更新するために、UIディスパッチャを使用して、その後、カメラは(複数の)別のスレッドでフィードを更新するParallel.Forを使用しています。

このような何か:

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 
    } 
} 
関連する問題