MapInfo Pro Developers User Group

Expand all | Collapse all

Handling events in .NET projects referenced in MapBasic

  • 1.  Handling events in .NET projects referenced in MapBasic

    Posted 04-01-2021 01:20
    Hello,

    I have been developing with MapBasic and .NET for a little while now and have frequently come across the issue that interfacing between MapInfo and .NET through a different thread than the main thread will cause MapInfo to crash.

    For example, .NET events will run their event handlers on a different thread to the main thread.

    What is the best way to handle this?

    Below is some sample code to demonstrate:

    // Creates a GeoCoordinateWatcher to track GPS coordinates
    GeoCoordinateWatcher watcher = new GeoCoordinateWatcher();
    this.onPositionChanged = new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);
    watcher.PositionChanged += this.onPositionChanged;
    watcher.TryStart(false, TimeSpan.FromMilliseconds(2000));

    // Here is the event that is triggered by the GeoCoordinate Watcher
    void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
    {
      PrintPosition(e.Position.Location.Latitude, e.Position.Location.Longitude);
    }

    // When calling MapBasic like this it will crash MapInfo with the error "The calling thread cannot access this object because a different thread owns it."
    // This error is found in the Windows Event Logs
    void PrintPosition(double latitude, double longitude)
    {
        this.mbxApplication.CallMapBasicSubroutine("PrintPosition", latitude.ToString(), longitude.ToString());
    }

    // When calling MapBasic like this it doesn't crash MapInfo but it locks up the UI
    void PrintPosition(double latitude, double longitude)
    {
      Action action = () =>
      {
        this.mbxApplication.CallMapBasicSubroutine("PrintPosition", latitude.ToString(), longitude.ToString());
      };
      Task task = new Task(action);
      task.RunSynchronously();
    }

    Any help will be greatly appreciated

    Regards
    Ben



    ------------------------------
    Ben Kleywegt
    Insight GIS
    ------------------------------


  • 2.  RE: Handling events in .NET projects referenced in MapBasic

    Posted 04-08-2021 08:16
    Hello Ben,
    Mapbasic code can only execute on a main UI thread so that exception is correct. To overcome this, you should execute MB command on a UI thread dispatcher.

    In you project create a static FrameworkElement object and use its dispatcher to execute all MB commands.

    Example:
    	public static class MBExecutor
    	{
    		public static FrameworkElement Element = new FrameworkElement();
    
    		public static void RunMBCommand(string cmd)
    		{
    			Element.Dispatcher.Invoke(() =>
    			{
    				// execute you code here.
    			});
    		}
    	}​

    Thanks
    Anshul

    ------------------------------
    Anshul Goel
    Knowledge Community Shared Account
    Shelton CT
    ------------------------------



  • 3.  RE: Handling events in .NET projects referenced in MapBasic

    Posted 04-08-2021 21:14
    Thanks Anshul, that works great.

    Cheers
    Ben

    ------------------------------
    Ben Kleywegt
    Insight GIS
    ------------------------------