ArcGIS Pro samples RunOnUiThread method

1442
2
07-27-2017 05:25 AM
GKmieliauskas
Esri Regular Contributor

Hi,

Some ArcGIS Pro samples ( Framework\DockPaneBookmarkAdvanced or Framework\DockpaneSimple) have Utils class with different implementations of RunOnUiThread and IsOnUiThread methods. I thought that it could be useful when you call some methods which must be called on MCT from different places. Sometimes you are on MCT, sometimes not. I have tried methods from both projects, but I failed. IsOnUiThread always said that code is on UI thread, but really it was not. So I started investigate why sample code works, but my not. I have looked at the methods which were used with RunOnUiThread and found that all of them use QueuedTask.Run inside. I have commented QueuedTask.Run and samples failed too.

Maybe I didn't understood the working RunOnUiThread functionality or it is bug?

Tags (1)
0 Kudos
2 Replies
CharlesMacleod
Esri Regular Contributor

Looks like DockpaneSimple and DockPaneBookmarkAdvanced have logic in OnUIThread for unit testing. For your uses you can ignore the "FrameworkApplication.TestMode" bit.

RunOnUIThread ensures that the action you specify (as the parameter) will always be executed on the UI thread.

Samples are written by different authors so one is using Application.Current.Dispatcher, the other System Task (and UIScheduler) but they both accomplish the same thing.

If you share some code where OnUIThread returns true (when it should return false) we can look into it. Here is a little test I wrote and it looks ok:

internal class Button1 : Button
  {

    public static bool IsOnUiThread => 
      ArcGIS.Desktop.Framework.FrameworkApplication.TestMode || 
      System.Windows.Application.Current.Dispatcher.CheckAccess();

    protected async override void OnClick()
    {
      bool fromUI = Button1.IsOnUiThread;
      bool fromQTR = await QueuedTask.Run(() => Button1.IsOnUiThread);
      bool fromSystemTask = await System.Threading.Tasks.Task.Run(() => 
            Button1.IsOnUiThread);

      MessageBox.Show(
        $"On UI?: {fromUI} (called from UI)\r\n" +
        $"On UI?: {fromQTR} (called from QTR)\r\n" +
        $"On UI?: {fromSystemTask} (called from System Task)");
    }
  }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Note, there is an API property you can use if you prefer called QueuedTask.OnGUI (also QueuedTask.OnWorker)

QueuedTask.OnGUI topic14880.html

0 Kudos
GKmieliauskas
Esri Regular Contributor

Hi Charles,

Thank you for the explanation. I have wrote method void RunOnMCTThread(Action action) using your information and it works fine.

0 Kudos