Создание потока в потоке пользовательского интерфейса .NET MAUI
В этой статье описывается, как использовать класс пользовательского интерфейса приложений .NET (.NET MAUI) MainThread для выполнения кода в основном потоке пользовательского интерфейса. Большинство операционных систем используют модель с одним потоком для кода с использованием пользовательского интерфейса. Такая модель необходима для правильной сериализации событий пользовательского интерфейса, например нажатий клавиш и сенсорного ввода. Этот поток часто называется основным потоком, потоком пользовательского интерфейса или потоком пользовательского интерфейса. Недостатком этой модели является то, что весь код с доступом к элементам пользовательского интерфейса должен выполняться в основном потоке приложения.
Класс MainThread
находится в пространстве имен Microsoft.Maui.ApplicationModel
.
Когда это необходимо
Иногда приложениям требуется использовать события, вызывающие обработчик событий в дополнительном потоке, например Accelerometer
датчики или Compass
датчики. Все датчики могут возвращать информацию о вторичном потоке при использовании с более быстрыми скоростями датчика. Если обработчик событий должен получить доступ к элементам пользовательского интерфейса, он должен вызвать код в основном потоке.
Выполнение кода в потоке пользовательского интерфейса
Чтобы запустить код в основном потоке, вызовите статический метод MainThread.BeginInvokeOnMainThread. Он принимает в качестве аргумента объект Action, который представляет собой метод без аргументов и возвращаемых значений:
MainThread.BeginInvokeOnMainThread(() =>
{
// Code to run on the main thread
});
Кроме того, можно определить отдельный метод для кода, а затем вызвать этот код с BeginInvokeOnMainThread
помощью метода:
void MyMainThreadCode()
{
// Code to run on the main thread
}
MainThread.BeginInvokeOnMainThread(MyMainThreadCode);
Определение обязательности вызова
MainThread С помощью класса можно определить, выполняется ли текущий код в основном потоке. Свойство MainThread.IsMainThread возвращается true
, если код, вызывающий свойство, выполняется в основном потоке, и false
если это не так. Предположим, что необходимо определить, выполняется ли код в основном потоке перед вызовом MainThread.BeginInvokeOnMainThread. Например, следующий код используется IsMainThread
для определения того, следует ли MyMainThreadCode
вызывать метод непосредственно, если код выполняется в основном потоке. Если он не выполняется в основном потоке, метод передается BeginInvokeOnMainThread
в:
if (MainThread.IsMainThread)
MyMainThreadCode();
else
MainThread.BeginInvokeOnMainThread(MyMainThreadCode);
Это проверка не требуется. BeginInvokeOnMainThread
Само по себе проверяет, выполняется ли текущий код в основном потоке или нет. Если код выполняется в основном потоке, BeginInvokeOnMainThread
просто вызывает предоставленный метод напрямую. Если код выполняется в дополнительном потоке, BeginInvokeOnMainThread
вызывает предоставленный метод в основном потоке. Таким образом, если выполняемый код совпадает, независимо от основного или вторичного потока, просто вызов BeginInvokeOnMainThread
без проверка, если это необходимо. В этом нет незначительных накладных расходов.
Единственная причина, по которой необходимо проверка IsMainThread
свойство, заключается в том, что у вас есть логика ветвления, которая делает что-то другое на основе потока.
Дополнительные методы
Класс MainThread включает следующие дополнительные методы static
, которые можно использовать для взаимодействия с элементами пользовательского интерфейса из фоновых потоков.
Способ | Аргументы | Возвраты | Назначение |
---|---|---|---|
InvokeOnMainThreadAsync<T> |
Func<T> |
Task<T> |
Вызывает объект Func<T> в основном потоке и ожидает его завершения. |
InvokeOnMainThreadAsync |
Action |
Task |
Вызывает объект Action в основном потоке и ожидает его завершения. |
InvokeOnMainThreadAsync<T> |
Func<Task<T>> |
Task<T> |
Вызывает объект Func<Task<T>> в основном потоке и ожидает его завершения. |
InvokeOnMainThreadAsync |
Func<Task> |
Task |
Вызывает объект Func<Task> в основном потоке и ожидает его завершения. |
GetMainThreadSynchronizationContextAsync |
Task<SynchronizationContext> |
Возвращает SynchronizationContext для основного потока. |