Search code examples
c#wpfuser-interfacedispatchermyo

Dispatcher not triggered during Myo hub initialization


I'm porting initialization code for a Myo armband to a WPF application, that uses a C# wrapper, http://goo.gl/HfwqQe to interact with the device.

But when I add the initialization code under the InitializeComponent(); in the code behind of my user control, the line to update a textbox with connection status is never triggered, this.Dispatcher.Invoke((Action)(() =>

I debugged this by setting a breakpoint on the line just before the dispatcher code and this is being called hub.MyoConnected += (sender, e) => meaning that the Myo has connected, but the following dispatcher line after that updates the statusTbxis never called and skipped over.

Anyone have any idea here what could be causing this?

I'm not sure why it won't output the connection status to the textbox. The same code worked before but this is a new version of the C# wrapper I'm using.

The console samples work fine, http://goo.gl/RFHLym and output connection to console, but I can't get it to output the connection to textbox instead.

This is the complete code for getting the Myo arm band's connection status :

using MyoSharp.Communication;
using MyoSharp.Device;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace MyoTestv4
{
    /// <summary>
    /// Interaction logic for ProductsView.xaml
    /// </summary>
    public partial class AdductionAbductionFlexionView : UserControl
    {
        public AdductionAbductionFlexionView()
        {
            InitializeComponent();



            // create a hub that will manage Myo devices for us
            using (var channel = Channel.Create(ChannelDriver.Create(ChannelBridge.Create())))
            using (var hub = Hub.Create(channel))
            {
                 //set a bpoint here, gets triggered
                // listen for when the Myo connects
                hub.MyoConnected += (sender, e) =>
                {
                     //set a bpoint here, doesn't get triggered
                    this.Dispatcher.Invoke((Action)(() =>
                    {
                        statusTbx.Text = "Myo has connected! " + e.Myo.Handle;
                        //Console.WriteLine("Myo {0} has connected!", e.Myo.Handle);
                        e.Myo.Vibrate(VibrationType.Short);

                    }));
                };

                // listen for when the Myo disconnects
                hub.MyoDisconnected += (sender, e) =>
                {
                    this.Dispatcher.Invoke((Action)(() =>
                    {
                        statusTbx.Text = "Myo has disconnected!";
                        //Console.WriteLine("Oh no! It looks like {0} arm Myo has disconnected!", e.Myo.Arm);
                        e.Myo.Vibrate(VibrationType.Medium);
                    }));
                };

                // start listening for Myo data
                channel.StartListening();
            }
        }
    }
}

Solution

  • You get this error because channel and hub are disposed immediately after calling

    channel.StartListening();
    

    using is a convenient way to dispose object for you, in this case, this is not desired. Please refer to using Statement (C# Reference) for more info.

    Try these steps to fix the problem. 1. Declare channel and hub as private field of the class. 2. Do not use using keyword. 3. Remember to dispose hub and channel when AdductionAbductionFlexionView is disposed of.

    public partial class AdductionAbductionFlexionView : UserControl
    {
        IChannel channel;
        IHub hub;
    
        public AdductionAbductionFlexionView()
        {
            InitializeComponent();
    
            // create a hub that will manage Myo devices for us
            channel = Channel.Create(ChannelDriver.Create(ChannelBridge.Create()));
            hub = Hub.Create(channel);
    
            //set a bpoint here, gets triggered
            // listen for when the Myo connects
            hub.MyoConnected += (sender, e) =>
            {
                //set a bpoint here, doesn't get triggered
                this.Dispatcher.Invoke((Action)(() =>
                {
                    statusTbx.Text = "Myo has connected! " + e.Myo.Handle;
                    //Console.WriteLine("Myo {0} has connected!", e.Myo.Handle);
                    e.Myo.Vibrate(VibrationType.Short);
    
                }));
            };
    
            // listen for when the Myo disconnects
            hub.MyoDisconnected += (sender, e) =>
            {
                this.Dispatcher.Invoke((Action)(() =>
                {
                    statusTbx.Text = "Myo has disconnected!";
                    //Console.WriteLine("Oh no! It looks like {0} arm Myo has disconnected!", e.Myo.Arm);
                    e.Myo.Vibrate(VibrationType.Medium);
                }));
            };
    
            // start listening for Myo data
            channel.StartListening();
        }
    }