0

I have this 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;

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

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

I want to the functionallity of StartButton to happen threw code, without me actually clicking it. The problem is that it is in the UI thread so I get an exception. I wastold that I should use Dispacher.Invoke for it but I am having a lot of troble doing so.

Is there a simple way to just invoke the button at run-time ?

Thanks

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
NotSure
  • 651
  • 2
  • 7
  • 24
  • 1
    Why don't you just call `StartCamera()` instead of trying to call an event on the button? – Lithium Apr 13 '17 at 11:09
  • Because when I do, I get en exception saying that another thread owns the reference (The startCamera function has 2 parameters that are UI, they are the messegeArea and the CameraList), this is the main problem I am having. I was told that there are some issues with the UIThread – NotSure Apr 13 '17 at 11:32
  • How to programmatically invoke the Button has already been answered here, hasn't it? http://stackoverflow.com/questions/43371849/pressing-a-button-using-code-button-function-is-async-in-c-sharp – mm8 Apr 13 '17 at 11:41
  • And you still *cannot" invoke it on any other thread than the dispatcher thread. – mm8 Apr 13 '17 at 11:42
  • Obviously if it was answered I wouldn't have asked here, I've tried all of the solutions there and nothing worked. I have a a current problem that I am seeking hep with. – NotSure Apr 13 '17 at 11:51
  • All of them work. It is your code that doesn't work because you try to run it on the wrong thread. – mm8 Apr 13 '17 at 11:59
  • Yes, I know that. None of them work for me. I am thankful for your help but if you don't have anything meaningful to say in this thread why waste both of our time with this conversation – NotSure Apr 13 '17 at 12:03

2 Answers2

2

I supppose that the exception is being thrown when you try to access the "MessageArea" Control from another thread because it's attached to the background UI thread, right?

Then you'll have to use Dispatcher.Invoke. ex: Instead of:

        MessageArea.Text = "No cameras found; cannot start processing";

Use:

Dispatcher.Invoke(new Action(() =>
            {
                MessageArea.Text = "No cameras found; cannot start processing";
            }));

For the CameraList you may do something like that:

 Dispatcher.Invoke(() =>
        {
            if (!CameraList.HasItems)
                //some logic
        });

For the last line and getting the SelectedIndex value from the CameraList:

var cameraListSelectedIndex = Dispatcher.Invoke(new Func<int>(() =>
        {
            return CameraList.SelectedIndex;
        }));
await _grabber.StartProcessingCameraAsync(cameraListSelectedIndex);

This should fix the problem.

shawkyz1
  • 886
  • 5
  • 19
  • Yes the MessegeArea.Text is one problem, the other is the CameraList, there I am not chaning anything just checking it, what can I do in those parts ? thank you – NotSure Apr 13 '17 at 11:50
  • for eample the last line of code in the return uses the CameraList which is in the UI and I get an exception because of it, the Dispacher.Invoke doesnt work for me there. – NotSure Apr 13 '17 at 12:05
  • Thank you for you help, You are getting me close with this, I am stuck on this for days. I get an error that says : "anonymous function converted to a void returing delegate cannot return a value". bassicly it doesn't approve of the boolean returning :( This is only regarding the last line of code the troubles me, await _grabber.StartProcessingCameraAsync(CameraList.SelectedIndex); – NotSure Apr 13 '17 at 13:02
  • you can get it synchronously. var selectedIndex = Dispatcher.Invoke(new Func(() => { return CameraList.SelectedIndex; })); – shawkyz1 Apr 13 '17 at 13:07
  • Thank you so much ! it works now, as a begginer in C# there was no way i could have solved it that you as this whole async functions still confuses me. – NotSure Apr 13 '17 at 13:19
0

You can use this code when you navigate to your page :

await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
   StartCamera();
});
sayah imad
  • 1,507
  • 3
  • 16
  • 24