Xamarin.Essentials: MainThread
Класс MainThread позволяет выполнять код в основном потоке приложения, а также проверять, выполняется ли конкретный блок кода в основном потоке в конкретный момент.
Большинство операционных систем, включая iOS, Android и универсальную платформу Windows, используют однопоточную модель для кода, имеющего отношение к пользовательскому интерфейсу. Такая модель необходима для правильной сериализации событий пользовательского интерфейса, например нажатий клавиш и сенсорного ввода. Этот поток может упоминаться как основной потоком, поток, обрабатывающий события от пользовательского интерфейса, или поток пользовательского интерфейса. Недостатком этой модели является то, что весь код с доступом к элементам пользовательского интерфейса должен выполняться в основном потоке приложения.
Иногда приложениям приходится использовать события, которые вызывают обработчик событий во второстепенном потоке выполнения. (Классы Xamarin.Essentials Accelerometer
, Compass
, Gyroscope
, Magnetometer
и OrientationSensor
могут возвращать сведения во второстепенном потоке, если работают с высокой скоростью.) Если обработчику событий нужен доступ к элементам пользовательского интерфейса, он должен выполнять соответствующий код в основном потоке. Класс MainThread позволяет приложениям выполнять код в основном потоке.
Чтобы начать использовать этот API, ознакомьтесь с руководством по началу работы с Xamarin.Essentials, чтобы правильно настроить и установить библиотеку в проектах.
Добавьте ссылку на Xamarin.Essentials в своем классе:
using Xamarin.Essentials;
Чтобы запустить код в основном потоке, вызовите статический метод MainThread.BeginInvokeOnMainThread
. Он принимает в качестве аргумента объект Action
, который представляет собой метод без аргументов и возвращаемых значений:
MainThread.BeginInvokeOnMainThread(() =>
{
// Code to run on the main thread
});
Также есть возможность определить отдельный метод для кода, который должен выполняться в основном потоке:
void MyMainThreadCode()
{
// Code to run on the main thread
}
Вы сможете запустить этот метод в основном потоке, передав ссылку на него в метод BeginInvokeOnMainThread
:
MainThread.BeginInvokeOnMainThread(MyMainThreadCode);
Примечание
Xamarin.Forms имеет метод с именем Device.BeginInvokeOnMainThread(Action)
, который делает то же, что и MainThread.BeginInvokeOnMainThread(Action)
.
Вы можете использовать в приложении Xamarin.Forms любой из этих методов, но при выборе желательно учитывать, есть ли у вызывающего кода любая другая зависимость от Xamarin.Forms. Если такой зависимости нет, обычно лучше использовать MainThread.BeginInvokeOnMainThread(Action)
.
Класс MainThread
позволяет приложению определить, выполняется ли конкретный блок кода в основном потоке. Свойство IsMainThread
возвращает значение true
, если обращающийся к нему код выполняется в основном потоке. Программа может использовать это свойство, чтобы условно запускать другой код в основном или второстепенном потоке:
if (MainThread.IsMainThread)
{
// Code to run if this is the main thread
}
else
{
// Code to run if this is a secondary thread
}
Возможно, у вас возникло желание проверять поток выполнения кода перед вызовом BeginInvokeOnMainThread
, например так:
if (MainThread.IsMainThread)
{
MyMainThreadCode();
}
else
{
MainThread.BeginInvokeOnMainThread(MyMainThreadCode);
}
Можно предположить, что такая проверка может повысить производительность, если блок кода уже выполняется в основном потоке.
Но на самом деле эта проверка не нужна. Все реализации платформ BeginInvokeOnMainThread
самостоятельно проверяют, выполняется ли вызов из основного потока. Если вы будете вызывать метод BeginInvokeOnMainThread
без реальной необходимости, это приведет к небольшому снижению производительности.
Класс 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 для основного потока. |