2017-08-21 10 views
2
var httpResponseMessage = await httpClient.SendAsync(message).ConfigureAwait(false); 
var dataStream = await httpResponseMessage.Content.ReadAsStreamAsync(); 

これはアイデアによるものですが、何が実行されてもメソッドが存在し、UIに戻ります。応答が到着すると実行が再開されますが、実際には実行されていないときにUIがすでにその実行を更新しています。 すべての呼び出しメソッドが待機されています。HttpClientt.SendAsync does not wait/lock実行

初期の方法は、その呼び出しは、UIが進行して更新する必要があります終えたが、2番目のhttpClient.SendAsyncが実行されると、実行がUIに戻り、HTTPClientのトリガーとなるUIメソッドの実行サービスを開始し、設計(Task.Run(() => StartDownload(selectedSchedules));で待望されていない

Task.Run(() => StartDownload(selectedSchedules)); //First call, initiated by a button 

public async Task StartDownload(SchedulesList list) 
{ 
    //var t = new Task(() => _scheduleServices.Download(list)); 
    //t.Start(); 
    //await t; 
    await _scheduleServices.DownloadIwcfDb(list, UsbInfoModels); 
} 

public async Task Download(SchedulesList schedulesList) 
{       
    await DownloadDb(schedulesList);   
} 

private async Task DownloadDb(SchedulesList schedulesList) 
{ 
    using (var httpClient = new HttpClient()) 
    { 
     var message = new HttpRequestMessage(new HttpMethod("POST"), ApiCallUrls.GetIwcfSchedules) 
     { 
      Content = new StringContent(JsonConvert.SerializeObject(schedulesList), Encoding.UTF8, "application/json") 
     }; 

     httpClient.Timeout = TimeSpan.FromMinutes(20); 
     var httpResponseMessage= await httpClient.SendAsync(message).ConfigureAwait(false); 
     var dataStream = await httpResponseMessage.Content.ReadAsStreamAsync(); 
     using (Stream contentStream = dataStream, stream = new FileStream(Path.Combine(Directories.SomEDir, Directories.SomeFileName), FileMode.Create, FileAccess.Write, FileShare.None)) 
     { 
      await contentStream.CopyToAsync(stream); 
     } 
    } 
} 

コールチェーン追加された無関係なコードがメソッドから削除されました

+0

が、これは –

+2

asyncを指定するためにセットにしてください走った方法でした(Task.Run()を使用するもの)のソースコードを提供する –

+0

@BenSteeleはい、httpclientを使用する必要があります。 –

答えて

4

あなたの問題はおそらく最初の呼び出しの中にあります。

あなたが持っているあなたのコードで

Task.Run(()=>StartDownload(selectedSchedules)); //First call, initiated by a button 
//I assume afterwards you update the ProgressBar or give some other progress feedback 

これが何をするかである:それはは実行を継続し、直ちにStartDownloadを呼び出します。他のすべてのもの(ダウンロードなど)はバックグラウンドで起こっています。メソッドStartDownloadはブロックされません。単にTaskオブジェクトを返します。 awaitそのTaskオブジェクトでなければ、コードは単純に処理されます。

私はあなたが望んでいると思う:StartDownloadを呼び出して、完了するのを待ってから、進捗状況を更新してください。

ボタンのイベントハンドラをasyncとマークし、さらにasyncを使用するのが簡単な解決方法です。この方法は少し次のようになります。

private async void HandleEvent() 
{ 
    await StartDownload(); 
    //update progress 
} 

私は非同期待つために導入のためのあなたのステファン・クリアリーからこのブログの記事をお勧めすることができます:https://blog.stephencleary.com/2012/02/async-and-await.html

+0

実際に私のコードの作品が判明、私は99%が前に出ていたと確信しています、私の最新のチャンを踏んでいない必要があります私はあなたの答えを受け入れるでしょう。大抵の場合、おそらく助けになるでしょう。私がかなり確信していましたが、私は実行が実行されるのを待つために非同期のイベントハンドラを必要とせず、チェーンに沿ってUIを更新しました(その部分は実際の実行には関係なく省略されました) –