Я думал, что я понял, 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;
}
Эти фрагменты кода работали. Но почему?
То, что я узнал, после ожидания configure установлено в значение false, код не запускается в SynchronizationContext
(который является потоком пользовательского интерфейса).
Если я сделаю метод OnBindViewHolder
асинхронным и OnBindViewHolder
использовать вместо Task.Run, код выйдет из строя
imageView.SetImageBitmap(bitmap);
Говорить, что это не в потоке пользовательского интерфейса, что имеет для меня совершенно смысл.
Так почему же async
/await
аварии коды в то время как Task.Run() не делает?
Обновление: ответ
Поскольку Task.Run не ожидалось, исключенное исключение не было показано. Если я ожидаю Task.Run, я ожидал ошибку. Дальнейшие объяснения можно найти в ответах ниже.