Search code examples
c#wpfmultithreadingbackgroundworker

How to use delegate BackgroundWorker?


I try to write a WPF application with Kinect, so I have write this code:

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

So when I try to execute this code this.sensorChooserUi.KinectSensorChooser = this.sensorChooser;, I Have this error:

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

How can I fixed it?


Solution

  • you need to invoke such calls on the main thread like this

    this.Dispatcher.Invoke(() =>
          this.sensorChooser = new KinectSensorChooser();
          this.sensorChooser.KinectChanged += SensorChooserOnKinectChanged;
          this.sensorChooserUi.KinectSensorChooser = this.sensorChooser;
          this.sensorChooser.Start();
          this.sensor = this.sensorChooser.Kinect;
    });
    

    you may have to wrap any such code in dispatcher calls.

    typically any calls to such elements have thread affinity so they require methods to be called using the same thread they are created on. in your case this.sensorChooserUi is created in a different thread then this.sensorChooser.

    Update

    you may have to selectively pick the piece of code which can be executed async. typically not every code is meant to be async. so do identify the expensive part of your code and do it async only if it allows. usually IO calls, network calls are good candidate for async. other approach is to find vulnerable part of your code and wrap it in dispatcher invoke.