Asynchronous deadlock?

I'm pretty sure I'm creating a dead end in my application, and I'm not sure how to solve the problem. I have some moving parts and am new to async and await , so please bear with me.

I have a client that downloads a file as follows:

 public static async Task<string> UploadToService(HttpPostedFile file, string authCode, int id) { var memoryStream = new MemoryStream(); file.InputStream.CopyTo(memoryStream); var requestContent = new MultipartFormDataContent(); var fileContent = new ByteArrayContent(memoryStream.ToArray()); fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse(file.ContentType); requestContent.Add(fileContent, "file", file.FileName); using (var httpClient = new HttpClient()) { httpClient.BaseAddress = new Uri(BaseUrl); httpClient.DefaultRequestHeaders.Accept.Clear(); var message = await httpClient.PostAsync( string.Format("Upload?authCode={0}&id={1}", authCode, id), requestContent); return await message.Content.ReadAsStringAsync(); } } 

Piece receiving file:

 [HttpPost] public Task<HttpResponseMessage> Upload(string authCode, int id) { var request = Request; var provider = new CustomMultipartFormDataStreamProvider(root); var task = request.Content.ReadAsMultipartAsync(provider) .ContinueWith(o => { // ... // Save file // ... return new HttpResponseMessage() { Content = new StringContent("File uploaded successfully"), StatusCode = HttpStatusCode.OK }; }); return task; } 

It all started with the following:

 protected void Page_Load(object sender, EventArgs e) { if (IsPostBack) { var file = HttpContext.Current.Request.Files[0]; var response = UploadToService(file, hiddenAuthCode.Value, int.Parse(hiddenId.Value)); } } 

Everything works, except that PostAsync will never recognize that task being returned. I see that the status of the await ... PostAsync ... task await ... PostAsync ... is WaitingForActivation, but I'm not quite sure what that means (remember that I am n00b for this stuff). My file is saved in the right place, but the application never recognizes the response from my service.

If someone can point me in the right direction, it will be very appreciated.

+8
c # async-await
source share
1 answer

I think the problem is that you just call UploadToService in fire and swell mode inside Page_Load . Request processing simply ends before this task is completed.

You should use <%@ Page Async="true" ...> WebForms on this page and include <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" /> in your web.config .

Then use RegisterAsyncTask , the code will look like this:

 protected void Page_Load(object sender, EventArgs e) { if (IsPostBack) { var file = HttpContext.Current.Request.Files[0]; RegisterAsyncTask(new PageAsyncTask(() => UploadToService(file, hiddenAuthCode.Value, int.Parse(hiddenId.Value)))); } } 

On the other hand, you can improve this part:

 file.InputStream.CopyTo(memoryStream); 

like this:

 await file.InputStream.CopyToAsync(memoryStream); 

and replace ContinueWith with async/await :

 [HttpPost] public async Task<HttpResponseMessage> Upload(string authCode, int id) { var request = Request; var provider = new CustomMultipartFormDataStreamProvider(root); await request.Content.ReadAsMultipartAsync(provider); return new HttpResponseMessage() { Content = new StringContent("File uploaded successfully"), StatusCode = HttpStatusCode.OK }; } 

Related: "Using asynchronous methods in ASP.NET 4.5 . "

+6
source share

All Articles