如何使用委托BackgroundWorker?

时间:2014-06-06 09:12:45

标签: c# wpf multithreading backgroundworker

我尝试用Kinect编写一个WPF应用程序,所以我写了这段代码:

    static BackgroundWorker _bw = new BackgroundWorker();
    _bw.DoWork += bw_DoWork;
    _bw.RunWorkerAsync();

    dispatcherTimerGame = new System.Windows.Threading.DispatcherTimer();
    dispatcherTimerGame.Tick += new EventHandler(dispatcher_VerificaCarte);
    dispatcherTimerGame.Interval = new TimeSpan(0, 0, 1);
    dispatcherTimerGame.Start();

    void bw_DoWork(object sender, DoWorkEventArgs e)
    {
       try
       {
          this.sensorChooser = new KinectSensorChooser();
          this.sensorChooser.KinectChanged += SensorChooserOnKinectChanged;
          this.sensorChooserUi.KinectSensorChooser = this.sensorChooser;
          this.sensorChooser.Start();
          this.sensor = this.sensorChooser.Kinect;
          if (this.sensor != null)
          {
             DateTime dat1 = DateTime.Now;
             string date = DateTime.Now.ToString("dd-MMM-yy HH-mm");
             acquisizioneVideo = new Acquisizione("Video" + date + ".avi");
             this.sensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
             acquisizioneAudio = new AcquisizioneWaveAudio(180, this.sensor, "Audio" + date + ".wav");     acquisizioneAudio.recordAudio();
             acquisizioneVideo.recordVideo();

             this.sensor.ColorFrameReady += acquisizioneVideo.ColorImageReady;

          }
       }
    catch (Exception exc)
    {
       log.Error(exc);
    }
}

所以当我尝试执行此代码时  this.sensorChooserUi.KinectSensorChooser = this.sensorChooser;, 我有这个错误:

[System.InvalidOperationException] = {"The calling thread cannot access this object because a different thread owns it."}"

我该如何解决?

1 个答案:

答案 0 :(得分:0)

你需要像这样

在主线程上调用这样的调用
this.Dispatcher.Invoke(() =>
      this.sensorChooser = new KinectSensorChooser();
      this.sensorChooser.KinectChanged += SensorChooserOnKinectChanged;
      this.sensorChooserUi.KinectSensorChooser = this.sensorChooser;
      this.sensorChooser.Start();
      this.sensor = this.sensorChooser.Kinect;
});

您可能必须在调度程序调用中包装任何此类代码。

通常对这些元素的任何调用都具有线程关联性,因此它们需要使用创建它们的相同线程调用方法。在你的情况下,this.sensorChooserUi是在一个不同的线程中创建的,然后是this.sensorChooser。

<强>更新

您可能必须选择性地选择可以执行异步的代码段。通常不是每个代码都是异步的。所以要确定代码中昂贵的部分,并且只有在允许时才进行异步。通常IO调用,网络调用是异步的良好候选者。另一种方法是查找代码中易受攻击的部分并将其包装在调度程序调用中。