Я думал, что достаточно хорошо понял async
/ await
и Task.Run()
, пока не столкнулся с этой проблемой:
Я программирую приложение Xamarin.Android, используя RecyclerView
с ViewAdapter
.В моем методе OnBindViewHolder я попытался асинхронно загрузить некоторые изображения
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
// Some logic here
Task.Run(() => LoadImage(postInfo, holder, imageView).ConfigureAwait(false));
}
Затем в своей функции LoadImage я сделал что-то вроде:
private async Task LoadImage(PostInfo postInfo, RecyclerView.ViewHolder holder, ImageView imageView)
{
var image = await loadImageAsync((Guid)postInfo.User.AvatarID, EImageSize.Small).ConfigureAwait(false);
var byteArray = await image.ReadAsByteArrayAsync().ConfigureAwait(false);
if(byteArray.Length == 0)
{
return;
}
var bitmap = await GetBitmapAsync(byteArray).ConfigureAwait(false);
imageView.SetImageBitmap(bitmap);
postInfo.User.AvatarImage = bitmap;
}
Эти кусочки кода сработали .Но почему?
Что я узнал, после того как для настройки конфигурации установлено значение false, код не запускается в SynchronizationContext
(который является потоком пользовательского интерфейса).
Если я сделаю OnBindViewHolder
метод async и использование await вместо Task.Run, код падает на
imageView.SetImageBitmap(bitmap);
Сказать, что он не в потоке пользовательского интерфейса, что для меня совершенно логично.
Так почему же происходит сбой кода async
/ await
, а Task.Run () не происходит?
Обновление: ответ
Поскольку Task.Run не ожидался, выброшенное исключение не было показано.Если я жду Task.Run, произошла ошибка, которую я ожидал.Дальнейшие объяснения можно найти в ответах ниже.