Поделиться через


Создание потока в потоке пользовательского интерфейса .NET MAUI

Browse sample. Обзор примера

В этой статье описывается, как использовать класс пользовательского интерфейса приложений .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 для основного потока.