2012-03-06 4 views
0

私はWPFでEmguCVを使用していますが、私はこのサンプルtpキャプチャイメージを見つけました。私はいくつかの他のメソッドMethod3()でbs1を使用したいのですが、何が問題なの?すべてのグローバル変数WPFスレッドエラー

BitmapSource bs1; 

private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     capture = new Capture();  ///capture image 

     timer = new DispatcherTimer();  // timer object 
     timer.Interval = new TimeSpan(500); 
     timer.Tick += new EventHandler(timer_Tick); 
     timer.Start(); 

    } 
    void timer_Tick(object sender, EventArgs e) 
    { 
     using ( Image<Bgr, byte> Frame = capture.QueryFrame()) 
     { 
      if (Frame != null) 
      { 
       bs1 = ToBitmapSource(Frame); 
webcam.Source = ToBitmapSource(Frame); // ToBitmapSource convert image to bitmapsource webcam is a picture in mainwindow 
       Frame.Save("fg.jpeg"); //this work but use lot of processing 

      } 
     } 
    } 


public void Method3_click (...) 
{ 
    use_of_bs1(bs1); 
} 


    private void use_of_bs1() 
    { 

     data.Text = "waiting..."; 

     System.Threading.ThreadPool.QueueUserWorkItem(Startwork); 
    } 


    private void Startwork(object state) 
    { 

     try 
     { 
      _work = _worker.bs1_analysis(bs1);  // it is where bs1 giving thread errorbs1_analysis is library function 
     } 
     catch (Exception ex) 
     { 
      Dispatcher.BeginInvoke(new ShowworkInformationDelegate(ShowworkInformation)); 
      MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); 
      return; 
     } 
     Dispatcher.BeginInvoke(new ShowWorkInformationDelegate(ShowWorkInformation)); 

    } 

/// ToBitmapsource機能が

public static BitmapSource ToBitmapSource(Emgu.CV.IImage image) 
    { 
     using (System.Drawing.Bitmap source = image.Bitmap) 
     { 
      IntPtr ptr = source.GetHbitmap(); 
      BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(ptr, IntPtr.Zero, Int32Rect.Empty, System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions()); 
      DeleteObject(ptr); 
      return bs; 
     } 
    } 
+0

http://blog.somecreativity.com/2008/01/10/wpf-equivalent-of-invokerequired/ – Mohit

+1

あなたが 'DispatcherTimer'を使用していることを考えると、あなたの' Tick() 'はディスパッチャスレッドで正しく起動されるため、特別なディスパッチが必要ありません。このエラーを引き起こしている機能を指定することは可能ですか?あなたが投稿したコード、または**公開されていないコード( 'Capture'クラスや' ToBitmapSource() '関数など)? –

+0

実際にはメソッド3がエラーを発生させるものです method3はbs1を使用するスレッドも使用するボタンです – murmansk

答えて

1

wpfリソースを作成し、それを別のスレッドで使用する場合は、オブジェクトを渡す前にオブジェクトに対してFreeze()を呼び出すことができます。これにより、別のスレッドで使用することが不変かつ合法になります。

+0

おかげでトリック – murmansk

1

あなたが説明したものを、BS1がWindow.Dispatcherに関連付けられているので、あなたはMethod3()内側にアクセスしたときにされたからである後BS1があります、例外が発生しました。その問題を解決するには、タイマーイベント(timer_Tick)では、この

public void Method3() 
{ 
    Action<BitmapSource> useBs1 = (source) => use_of_bs1(source); 
    if(Thread.CurrentThread == this.Dispatcher.Thread) 
     { 

    useBs1(bs1); 
} 
else 
{ 
    this.Dispatcher.Invoke(DispatcherPriority.Normal,userBs1, bs1); 
} 


} 
1

ような何かを行うことができ、あなたはBS1は

に属し1あなたは上のイベントを実行する必要があることを別のスレッドにしていますメインスレッド。何かのように:WPFで

void timer_Tick(object sender, EventArgs e) 
{ 
    Dispatcher.Invoke(DispatcherPriority.Normal, 
      new Action(
       delegate { 
    using ( Image<Bgr, byte> Frame = capture.QueryFrame()) 
    { 
     if (Frame != null) 
     { 
      bs1 = ToBitmapSource(Frame); 
      webcam.Source = ToBitmapSource(Frame); // ToBitmapSource convert image to bitmapsource 
      Frame.Save("fg.jpeg"); //this work but use lot of processing 

     } 
    }})); 
} 
+0

実際にはエラーを発生させる方法3です – murmansk

2

、UI要素にのみアクセスすることができ、(凍結可能な要素を除く)、それらを作成した同じスレッドによって使用されます。コードでは、bs1がメインのUIスレッドで作成されます。異なるスレッドであるタイマーは、そのリソースにアクセスできません。

Dispatcher.Invoke(DispatcherPriority.Normal, new Action(()=>DoSomeCodeWithUIElement())); 

使用Dispatcher.Invokeあなたは非同期呼び出しをしたい場合の操作は、同期またはDispatcher.BeginInvoke実行したい場合は:あなたは、メインUIスレッド上で作成されたUI要素で何かをしたいときはいつでも は、次の操作を行います。 DoSomeCodeWithUIElementは、UI要素にアクセスして最終的に更新する方法です。

関連する問題