Reputation: 811
var httpResponseMessage = await httpClient.SendAsync(message).ConfigureAwait(false);
var dataStream = await httpResponseMessage.Content.ReadAsStreamAsync();
This by idea should be awaited, but no matter what it do executions exists the method and returns to UI. Execution resumes when responses arrives, but by that time UI has already updated that execution finished, when in fact it hasn't. All calling methods are awaited.
Initial method is not awaited by design (Task.Run(() => StartDownload(selectedSchedules));
which starts UI method executing services that triggers httpclient, when that call finished UI should update with progress, but the second httpClient.SendAsync
is executed, execution returns to UI
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);
}
}
}
Call Chain Added, irrelevant code removed from the methods
Upvotes: 2
Views: 1628
Reputation: 2663
You're problem probably lies within your first call.
In your code you have:
Task.Run(()=>StartDownload(selectedSchedules)); //First call, initiated by a button
//I assume afterwards you update the ProgressBar or give some other progress feedback
What this does is: It calls StartDownload
and immediately continues execution. All the other stuff (downloading etc) is then happening in the background. Remember that the method StartDownload
does not block; it simply returns a Task
object. If you do not await
that Task
object, the code will simply proceed.
I guess what you wanted is: Call StartDownload
, wait for it to finish, then update the progress.
A quick solution would be to mark your event handler of the button with async
, and then use async
all the way. The method would look a bit like this:
private async void HandleEvent()
{
await StartDownload();
//update progress
}
I can recommend you this blog post from Stephen Cleary for an introduction to async-await: https://blog.stephencleary.com/2012/02/async-and-await.html
Upvotes: 4