У меня есть несколько общих вопросов о многопоточности при разработке приложений .NET / UWP. Я возьму в качестве примера UWP.
[Аксиома 1] В UWP у нас есть поток пользовательского интерфейса (где выполняется все об элементах пользовательского интерфейса: init, повышение событий и т. Д.) И поток без пользовательского интерфейса.
- При создании новой библиотеки (в нашем случае - библиотеки UWP), ИЛИ при вызове методов .NET, ИЛИ при возникновении события, не связанного с пользовательским интерфейсом (например, из обновления DeviceWatcher). событие), следует помнить , что мы не знаем , в каком потоке он будет работать?
Мы хотим изменить элемент пользовательского интерфейса в обработчике события обновления DeviceWatcher. Должны ли мы всегда знать , что мы не знаем, в каком потоке он работает? Поэтому нам необходимо:
private async void DeviceWatcher_Updated(DeviceWatcher sender, DeviceInformation deviceInfo)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
// ToDo
});
}
или в случае наличия / создания пользовательского класса:
public class MyClass
{
// ...
public async Task ModifySomethingOnUIThread()
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
// ToDo
});
}
}
В общем случае .NET документация не указывает для каждой сущности .NET (метод, событие) поведение по умолчанию. В частности, в каком потоке будет запущен первый код - без Dispatcher.RunAsync ()?
Кроме того, с точки зрения архитектуры
должны ли мы управлять зависимыми от потока делами
в нашем методе или
, чтобы вызывающая сторона знала об этом аспекте -возможно добавление в описание
Вы должны запустить этот метод в потоке пользовательского интерфейса. ? (потому что, опять же, у нас есть плюсы и минусы: проще управлять в вашей библиотеке (например, методом), но с другой стороны, мы ничего не должны знать о пользовательском интерфейсе). [В частности, «кто» переносит Dispatcher.RunAsync () - вызывающая сторона или вызываемая сторона]
Это только некоторые примеры. Но мы также можем говорить о потоках X и Y.