Android.OS.NetworkOnMainThreadException:在async / await块中

时间:2016-12-11 11:40:18

标签: c# android asynchronous xamarin xamarin.android

我试图从URL中获取绘图,指向图像。但问题是,在android中你不应该在主线程上执行网络任务。因为它,我使用async / await块,但错误仍然一直发生。这是代码:

page.Appearing += async(sender, ev3) =>
                    {
                        if ( GetToolbar == null ) return;

                        GetToolbar.Subtitle = viewModel?.SubTitle;

                        if ( viewModel == null ) return;

                        if ( viewModel.AvatarUrl.Contains("?") && !viewModel.AvatarUrl.Contains("gravatar") )
                            viewModel.AvatarUrl = viewModel.AvatarUrl
                                .Substring(0, viewModel.AvatarUrl.IndexOf("?", StringComparison.Ordinal));

                        //var stream = Context.ContentResolver.OpenInputStream(Android.Net.Uri.Parse(viewModel.AvatarUrl));

                        await SetLogo(viewModel);
 }

private async Task SetLogo(PublicRepositoryPageViewModel viewModel)
        {
            var url = new URL(viewModel.AvatarUrl);
            var connection = url.OpenConnection();
            var stream = connection.InputStream;
            var logo = await Drawable.CreateFromStreamAsync(stream, viewModel.Title + "_avatar");
            GetToolbar.Logo = logo;
        }

确切地说,它出现在这一行:

var stream = connection.InputStream;

如果我使用OpenInputStream而不是它,那么它会抛出 Java.IO.FileNotFoundException:没有内容提供者:https://avatars.githubusercontent.com/u/6516107

我已检查过互联网许可。

这是Xamarin.Forms Android项目

解答:

await Task.Run(async() => {
                            var url = new URL(viewModel.AvatarUrl);
                            var connection = url.OpenConnection();
                            var stream = connection.InputStream;
                            var logo = await Drawable.CreateFromStreamAsync(stream, viewModel.Title + "_avatar");
                            Device.BeginInvokeOnMainThread(()=>GetToolbar.Logo = logo);
                        });

1 个答案:

答案 0 :(得分:3)

Task.Run会让你离开主线程并进入默认Threadpool中的一个线程:

await Task.Run(async() => {
  var url = new URL(viewModel.AvatarUrl);
  var connection = url.OpenConnection();
  var stream = connection.InputStream;
  var logo = await Drawable.CreateFromStreamAsync(stream, viewModel.Title + "_avatar");
  GetToolbar.Logo = logo;
});