42

I have some file to upload and some of the files failed because the post is asynchronous and not synchronous..

I'm trying to make this call as synchronized call..

I want to wait for the response.

How can I make this call as synchronous?

static async Task<JObect> Upload(string key, string url, string 
                                 sourceFile, string targetFormat)
{ 
    using (HttpClientHandler handler = new HttpClientHandler { 
                                           Credentials = new NetworkCredential(key, "") 
                                       })
    using (HttpClient client = new HttpClient(handler))
    {
         var request = new MultipartFormDataContent();
         request.Add(new StringContent(targetFormat), "target_format");
         request.Add(new StreamContent(File.OpenRead(sourceFile)),
                                       "source_file",
                                        new FileInfo(sourceFile).Name);

        using (HttpResponseMessage response = await client.PostAsync(url,
                                                           request).ConfigureAwait(false))

        using (HttpContent content = response.Content)
        {
            string data = await content.ReadAsStringAsync().ConfigureAwait(false);
            return JsonObject.Parse(data);
        }
    }
}

Any help appreciated!

Darrel Miller
  • 139,164
  • 32
  • 194
  • 243
Alon Shmiel
  • 6,753
  • 23
  • 90
  • 138
  • 1
    Could you post more details about the failure? Asynchronous execution shouldn't be causing the upload to fail. If you really must you can use Task.Wait and check the return value to see if the task completed. https://msdn.microsoft.com/en-us/library/dd235606(v=vs.110).aspx – Rikki Gibson Jun 30 '15 at 05:00
  • 1
    I think you should not be using ConfigureAwait. Please check without ConfigureAwait. – Amit Jun 30 '15 at 05:11
  • @rikkigibson continuing after `await` on raw thread from thread pool (without HttpContext/Culture or UI thread configured correctly) generally will case NRE in the caller of the method (neither calling code nor error nor framework is shown by OP so hard to pinpoint problem). As Amit pointed out `ConfigureAwait` is usually way to get code working incorrectly (in hope to solve some other sync issues). I.e. here is discussion on ASP.Net usage of it - http://stackoverflow.com/questions/13489065/best-practice-to-call-configureawait-for-all-server-side-code . – Alexei Levenkov Jun 30 '15 at 05:19
  • without configureAwait=false, the upload is not finished.. So I read this blog and added it: http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html – Alon Shmiel Jun 30 '15 at 06:01
  • 4
    @AlonShmiel: To be clear, the upload is not failing because it's asynchronous, but because there's code upstream that is blocking on it. `ConfigureAwait(false)` is just a hacky workaround; the proper fix is to change the calling code to be asynchronous instead of blocking. – Stephen Cleary Jun 30 '15 at 12:06

2 Answers2

81

change

await content.ReadAsStringAsync().ConfigureAwait(false)

to

content.ReadAsStringAsync().Result

the ReadAsStringAsync returns a Task object. the '.Result' in the end of the line tell the compiler to return the inner string.

michael berezin
  • 1,146
  • 7
  • 8
0

That should do it:

static async Task<JObect> Upload(string key, string url, string 
                             sourceFile, string targetFormat)
{ 
    using (HttpClientHandler handler = new HttpClientHandler { 
                                           Credentials = new NetworkCredential(key, "") 
                                   })
    using (HttpClient client = new HttpClient(handler))
    {
         var request = new MultipartFormDataContent();
         request.Add(new StringContent(targetFormat), "target_format");
         request.Add(new StreamContent(File.OpenRead(sourceFile)),
                                   "source_file",
                                    new FileInfo(sourceFile).Name);

        using (HttpResponseMessage response = await client.PostAsync(url,request))

        using (HttpContent content = response.Content)
        {
            string data = await content.ReadAsStringAsync();
            return JsonObject.Parse(data);
        }
    }
}
NCC-2909-M
  • 709
  • 1
  • 7
  • 15
  • 1
    without configureAwait(false), the upload is not finished.. So I read this blog and added it: http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html – Alon Shmiel Jun 30 '15 at 06:02