HTTP Handler async issue .NET 4.5.2

2.7k views Asked by At

I am using .NET 4.5.2 for a web application and I have a HTTP handler that returns a processed image. I am making async calls to the process handler using jQuery and i have started getting the following error:

An asynchronous operation cannot be started at this time. Asynchronous operations may only be started within an asynchronous handler or module or during certain events in the Page lifecycle. If this exception occurred while executing a Page, ensure that the Page is marked <%@ Page Async="true" %>. This exception may also indicate an attempt to call an "async void" method, which is generally unsupported within ASP.NET request processing. Instead, the asynchronous method should return a Task, and the caller should await it.

This is the handler code:

       public void ProcessRequest(HttpContext context)
    {
        string CaseID = context.Request.QueryString["CaseID"].ToString();
        int RotationAngle = Convert.ToInt16(context.Request.QueryString["RotationAngle"].ToString());
        string ImagePath = context.Request.QueryString["ImagePath"].ToString();

        applyAngle = RotationAngle;

        string ImageServer = ConfigurationManager.AppSettings["ImageServerURL"].ToString();
        string FullImagePath = string.Format("{0}{1}", ImageServer, ImagePath);

        WebClient wc = new WebClient();
        wc.DownloadDataCompleted += wc_DownloadDataCompleted;
        wc.DownloadDataAsync(new Uri(FullImagePath));
    }

    private void wc_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
    {
        Stream BitmapStream = new MemoryStream(e.Result);

        Bitmap b = new Bitmap(BitmapStream);
        ImageFormat ImageFormat = b.RawFormat;

        b = RotateImage(b, applyAngle, true);

        using (MemoryStream ms = new MemoryStream())
        {
            if (ImageFormat.Equals(ImageFormat.Png))
            {
                HttpContext.Current.Response.ContentType = "image/png";
                b.Save(ms, ImageFormat.Png);
            }

            if (ImageFormat.Equals(ImageFormat.Jpeg))
            {
                HttpContext.Current.Response.ContentType = "image/jpg";
                b.Save(ms, ImageFormat.Jpeg);
            }
            ms.WriteTo(HttpContext.Current.Response.OutputStream);
        }
    }

Any idea what this means and I could do to overcome this?

Thanks in advance.

1

There are 1 answers

1
Panagiotis Kanavos On BEST ANSWER

You code won't work as it is, because you create a WebClient inside the ProcessRequest method but don't wait for it to finish. As a result, the client will be orphaned as soon as the method finishes. By the time a response arrives, the request itself has finished. There is no context or output stream to which you can write the response.

To create an asynchronous HTTP Handler you need to derive from the HttpTaskAsyncHandler class and implement the ProcessRequestAsync method:

public class MyImageAsyncHandler : HttpTaskAsyncHandler
{

   public override async Task ProcessRequestAsync(HttpContext context)
   {
      //...
      using(WebClient wc = new WebClient())
      {
          var data=await wc.DownloadDataTaskAsync(new Uri(FullImagePath));        
          using(var BitmapStream = new MemoryStream(data))
          {
              //...
              ms.WriteTo(context.Response.OutputStream);
             //...
          }
      }
   }
}