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

Cette idée devrait être attendue, mais peu importe ce qu'il fait, exécute la méthode et retourne à l'interface utilisateur. L'exécution reprend lorsque les réponses arrivent, mais à ce moment-là, l'interface utilisateur a déjà mis à jour l'exécution terminée, alors que ce n'est pas le cas. Toutes les méthodes d'appel sont attendues.HttpClientt.SendAsync n'attend pas/verrouille l'exécution

méthode initiale n'est pas attendu par la conception (Task.Run(() => StartDownload(selectedSchedules)); qui démarre les services d'exécution de la méthode de l'interface utilisateur qui déclenche httpclient, lorsque cet appel a terminé l'interface utilisateur doit mettre à jour avec le progrès, mais la deuxième httpClient.SendAsync est exécuté, l'exécution retourne à l'assurance-chômage

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

Chaîne d'appel Ajout d'un code non pertinent supprimé des méthodes

+0

La méthode choisie ce couru dans le jeu pour être async –

+2

s'il vous plaît fournir le code source de la fonction d'appel (celui utilisant le 'Task.Run()') –

+0

@BenSteele oui, doit être d'utiliser httpclient, chaîne d'appel ajoutée –

Répondre

4

Votre problème est probablement lié à votre premier appel.

Dans votre code que vous avez:

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

Ce que cela fait est: Il appelle StartDownload et immédiatement poursuit son exécution. Tout le reste (téléchargement, etc.) se passe alors en arrière-plan. Rappelez-vous que la méthode StartDownload ne bloque pas; il renvoie simplement un objet Task. Si vous ne await cet objet Task, le code va simplement procéder.

Je suppose que ce que vous vouliez est: Appelez StartDownload, attendez qu'il se termine, puis mettre à jour la progression.

Une solution rapide serait de marquer votre gestionnaire d'événements du bouton avec async, puis utiliser async tout le chemin. La méthode ressemblerait un peu comme ceci:

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

Je peux vous recommander ce post de blog de Stephen Cleary pour une introduction à Async-await: https://blog.stephencleary.com/2012/02/async-and-await.html

+0

En fait, mon code fonctionne, je suis sûr à 99% qu'il sortait avant, ne doit pas avoir traversé mon dernier chan Je vais accepter votre réponse, car cela aiderait probablement dans la majorité des cas. Bien que j'étais assez certain que je n'avais pas besoin d'un gestionnaire d'événements asynchrone pour attendre mon exécution car l'exécution est attendue de l'intérieur et met à jour l'interface utilisateur le long de la chaîne (cette partie a été omise car non liée à l'exécution) –