-3

I have a button that starts my camera. I want to sometimes start the camera dinammicly threw code, without pressing the button.

the code:

private async void StartCamera()
{
    if (!CameraList.HasItems) //-------> CameraList is in the UI
    {
        MessageArea.Text = "No cameras found; cannot start processing";
        return;
    }

    // Clean leading/trailing spaces in API keys. 
    Properties.Settings.Default.FaceAPIKey = Properties.Settings.Default.FaceAPIKey.Trim();
    Properties.Settings.Default.EmotionAPIKey = Properties.Settings.Default.EmotionAPIKey.Trim();
    Properties.Settings.Default.VisionAPIKey = Properties.Settings.Default.VisionAPIKey.Trim();

    // Create API clients. 
    _faceClient = new FaceServiceClient(Properties.Settings.Default.FaceAPIKey);
    _emotionClient = new EmotionServiceClient(Properties.Settings.Default.EmotionAPIKey);
    _visionClient = new VisionServiceClient(Properties.Settings.Default.VisionAPIKey);

    // How often to analyze. 
    _grabber.TriggerAnalysisOnInterval(Properties.Settings.Default.AnalysisInterval);

    // Reset message. 
    MessageArea.Text = ""; // -------> MessageArea is in the UI

    // Record start time, for auto-stop
    _startTime = DateTime.Now;


    await _grabber.StartProcessingCameraAsync(CameraList.SelectedIndex); // This is the problem, with the previous two I just can skip it, but here I can't avoid the CameraList
}

private async void StartButton_Click(object sender, RoutedEventArgs e)
{
    StartCamera();
}

I must tell that the CameraList variable is a UI combobox.

So when I try to use the StartCamera function I get an exception that says {"The calling thread cannot access this object because a different thread owns it."}

The same thing happnes when I try to use the startButton UI and using:

    StartButton.RaiseEvent(new RoutedEventArgs(System.Windows.Controls.Primitives.ButtonBase.ClickEvent));

in a previous thread I was told: "You can only access a UI element from the thread on which it was originally created, i.e. the UI thread. So you cannot run your code on a background thread. This has nothing to do with your original question about how to invoke the event handler though. Please ask a new question if you have another issue."

So here I am.

NotSure
  • 651
  • 2
  • 7
  • 24
  • 1
    You need to specify which line throws the execption. Also it is a bad habit to `async void` for anything that is not a event handler. Make your function `async Task` instead. – Scott Chamberlain Apr 12 '17 at 16:46
  • Per the marked duplicate, you can use a variety of approaches, but in your case, `Dispatcher.Invoke()` seems most appropriate. You need to invoke the code that calls `StartCamera()` or `StartButton.RaiseEvent()` using `Dispatcher.Invoke()`. Even better, use good MVVM practices so that you don't have the direct assignments to `MessageArea.Text` and the other direct access of UI objects that are causing your problem, then you can call `StartCamera()` directly without `Dispatcher.Invoke()` and WPF will handle the cross-thread behavior for you automatically. – Peter Duniho Apr 12 '17 at 16:53
  • Edited, basiclly the CameraList and MessageArea variables are in the UI. I can skip the two lines but can't skip the last return line of code that includes CameraList. – NotSure Apr 12 '17 at 16:53
  • I can't seem to make the Dispacher.Invoke() work, would you mind showing a simple example of it ? I was looking for it but nothing seems to work for me. – NotSure Apr 12 '17 at 18:11

1 Answers1

-1

I was going to post some sample code for you, but there are a bunch of good answers on this thread How to update the GUI from another thread in C#?.

Basically, you have to use a delegate to call back to the thread the ui is running on. This is because you want all ui modifications / input to be serialized. You don't want 2 different threads changing something in the ui at the same time. In my experience, it's not a bad idea to surround the method you are calling back with a lock as well, just as an added layer of protection against race conditions.

Anyway, give that link a look. It should help you out.

Community
  • 1
  • 1