English 中文(简体)
For Dotnet Maui, what the difference between Application.Current?.Dispatcher.Dispatch(async()) and MainThread.InvokeOnMainThreadAsync
原标题:

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.

问题回答

tl;dr: "best practice" is to use Dispatcher on some UI object. this.Dispatcher.Dispatch in code-behind.
If you only have one window, MainThread.BeginInvokeOnMainThread is equivalent. No difference in behavior. BUT TBD how to write unit tests if you refer to MainThread.


UPDATE: DispatcherQueue alternative for multi-window Windows app, to pick correct dispatcher when not in code-behind. (If you only have one window, MainThread is simpler, when not in code-behind. And works cross-platform.)


mattleibow s explanation. Thanks to Ligun Shen-MSFT for this link as a comment on question.

... The MainThread is static so it is mostly correct. Let me explain.

When you have a UI component (BindableObject, Button, Page, Window), it knows which thread it is assigned to. Some platforms, like Windows and iOS, require that UI objects be created on the UI thread. It will throw otherwise. And, the dispatcher is initialized to that thread.

MainThread has no concept of the UI thread so picks the first one. In most cases, it is correct because most platforms only have 1 "main thread". Windows is an outlier to this because it supports windows on separate threads. ...


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.


Nitty-gritty details:

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. So is MainThread.BeginInvokeOnMainThread. These two behave identically; it doesn t matter which you use in this case. However, consider various points below, such that Dispatcher is slightly favored as "best practice".

  • 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).





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签