2016-12-11 1 views
0

URLから描画可能なイメージを取得しようとしています。しかし、問題は、アンドロイドではメインスレッドでネットワークタスクを実行すべきではないということです。そのため、async/awaitブロックを使用しますが、エラーは常に発生します。ノーコンテンツプロバイダ:https://avatars.githubusercontent.com/u/6516107Android.OS.NetworkOnMainThreadException:async/awaitブロック内

var stream = connection.InputStream; 

私が代わりにそれのOpenInputStreamを使用する場合には、それは Java.IO.FileNotFoundExceptionをスロー:

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

まさにそれがこの行に発生します。ここでは、コードです

インターネットのアクセス許可を確認しました。

それは

ANSWER 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

Task.Runは、メインスレッドをオフし、デフォルトのスレッドプール内のスレッドにあなたを取得します:

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; 
}); 
+0

あなたはラムダの前にasyncキーワードを見逃しました。 ありがとうございます。それはトリックをした。多分あなたは何らかの情報源を持っているかもしれません。 –

+0

@ YuraBabiyありがとう、私は不足している '非同期'を修正します。 – SushiHangover

+1

'async'でメソッドにタグを付けるだけで、メソッド本体が別のスレッドを実行することはありません。今度は待っているタスクに達すると、それはスレッドプールに(デフォルトで)プッシュして、呼び出しスレッドをブロックしていない(したがって、非同期関数を持っている)ようになり、起動したスレッドを "オフ"にします、メインのUIメッセージング/ルーパースレッド。待機しているタスクが完了すると、残りのメソッドは引き続き実行され(これらは「継続」と呼ばれます)、スレッドプール上で実行されます(デフォルトの 'SynchronizationContext'はスレッドプールベースですが変更可能です) – SushiHangover

関連する問題