了解异步/等待和Task.Run()

编程入门 行业动态 更新时间:2024-10-27 04:31:15
本文介绍了了解异步/等待和Task.Run()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我以为我很了解 async / await 和 Task.Run(),直到遇到此问题为止:

I thought I understood async/await and Task.Run() quite well until I came upon this issue:

我正在使用 RecyclerView 和 ViewAdapter 对Xamarin.Android应用进行编程.在我的 OnBindViewHolder 方法中,我试图异步加载一些图像

I'm programming a Xamarin.Android app using a RecyclerView with a ViewAdapter. In my OnBindViewHolder Method, I tried to async load some images

public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position) { // Some logic here Task.Run(() => LoadImage(postInfo, holder, imageView).ConfigureAwait(false)); }

然后,在我的 LoadImage 函数中,我做了类似的事情:

Then, in my LoadImage function I did something like:

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; }

这些代码段有效.但为什么?

That pieces of code worked. But why?

我了解到的是,将configure await设置为false后,代码不会在 SynchronizationContext (这是UI线程)中运行.

What I've learned, after configure await is set to false, the code doesn't run in the SynchronizationContext (which is the UI thread).

如果我使 OnBindViewHolder 方法异步并使用await而不是Task.Run,​​则代码会在

If I make the OnBindViewHolder method async and use await instead of Task.Run, the code crashes on

imageView.SetImageBitmap(bitmap);

说它不在UI线程中,这对我来说完全有意义.

Saying that it's not in the UI thread, which makes totally sense to me.

那么为什么Task.Run()没有运行时, async / await 代码崩溃了?

So why does the async/await code crash while the Task.Run() doesn't?

更新:答案

由于未等待Task.Run,​​因此不会显示抛出的异常.如果我等待Task.Run,​​那是我所期望的错误.进一步的解释可以在下面的答案中找到.

Since the Task.Run was not awaited, the thrown exception was not shown. If I awaitet the Task.Run, there was the error i expected. Further explanations are found in the answers below.

推荐答案

这就像您不等待Task.Run一样简单,因此异常会被吞噬,并且不会返回到Task.Run的调用站点.

It's as simple as you not awaiting the Task.Run, so the exception gets eaten and not returned to the call site of Task.Run.

在Task.Run前面添加"await",您将获得异常.

Add "await" in front of the Task.Run, and you'll get the exception.

这不会使您的应用程序崩溃:

This will not crash your application:

private void button1_Click(object sender, EventArgs e) { Task.Run(() => { throw new Exception("Hello");}); }

但是,这会使您的应用程序崩溃:

This however will crash your application:

private async void button1_Click(object sender, EventArgs e) { await Task.Run(() => { throw new Exception("Hello");}); }

更多推荐

了解异步/等待和Task.Run()

本文发布于:2023-11-03 07:42:03,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1554597.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:Task   Run

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!