Home > Software engineering >  For Dotnet Maui, what the difference between Application.Current?.Dispatcher.Dispatch(async()) and M
For Dotnet Maui, what the difference between Application.Current?.Dispatcher.Dispatch(async()) and M

Time:12-15

Title says it all, docs don't seem to say which should be preferred. They have the same arguments you can pass basically too.

https://learn.microsoft.com/en-us/dotnet/api/microsoft.maui.applicationmodel.mainthread.invokeonmainthreadasync?view=net-maui-7.0

https://learn.microsoft.com/en-us/dotnet/api/microsoft.maui.dispatching.dispatcherextensions.dispatchasync?view=net-maui-7.0#microsoft-maui-dispatching-dispatcherextensions-dispatchasync(microsoft-maui-dispatching-idispatcher-system-action)

I think they both do the same thing functionally but I need to know best practice for my company's app. I don't see this question around already either.

CodePudding user response:

tl;dr: "best practice" is to call Dispatcher on some UI object.

From senior Microsoft techie Rob Caplan's answer (google Rob Caplan Microsoft for more info about who he is):

"InvokeOnMainThread was an oversimplification - not all apps have a main thread or a singular UI thread. Associating the Dispatcher to a UI object (which will in turn be tied to a thread) is more general and better supports multi-window applications."

That is: accessing the Dispatcher on some UI object is "more general" than using MainThread.


IF this is a Single Window app, AND you are writing code that is not code-behind (not part of a UI object), THEN Application.Current.Dispatcher is convenient and safe.

  • MOCK TESTING: its easier to make a mock IDispatcher, than to replace MainThread static class.

DETAILS:

  • If you are in code-behind (code associated with some UI object), use this.Dispatcher.... (You can omit this.; I just added it for clarity.)

  • If you are NOT in code-behind, and ARE in a single window app, Application.Current.Dispatcher and MainThread methods behave identically. HOWEVER, Application.Current.Dispatcher is preferred, because it is an IDispatcher object. Thus, it has the same syntax as the above "code-behind" case. And you can easily refactor some logic, if you need to pass to a different IDispatcher. E.g. for MOCK TESTING. OR if in the future your code gets used in a multi-window app.

  • DO NOT use EITHER MainThread nor Application.Current.Dispatcher in a multi-window app. You MUST get hold of a UI object on the window being touched. If you are writing code in a UI element, use this.Dispatcher. [this. is optional; shown for clarity.] OR pass in to your method a reference to any UI element of that window (someUIElement.Dispatcher).


Technical Note:

Does the presence of Dispatcher property mean App is "a UI object"?

[OPINION] Not quite. IMHO, any class which descends from VisualElement is "a UI object". These can be shown on a display.

App is partially compatible with UI objects, because both VisualElement and App inherit from Microsoft.Maui.Controls.Element.

Importantly, for this answer, Element inherits from BindableObject, which defines Dispatcher property.

What's missing from App, that is in all VisualElements?

Navigation. Style. And a long list of Properties related to display (Window, IsVisible, Width and Height, etc.)

CodePudding user response:

From the dotnet discord in the advanced questions 333fred posted an answer from the documentation to me. THANK YOU! If he updates here upvote him for it.

Answer: Use MainThread. NOT Application...Dispatch

I still don't know the difference but I do know best practice.

https://learn.microsoft.com/en-us/dotnet/maui/platform-integration/appmodel/main-thread?view=net-maui-7.0

  • Related