Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Async EventHandlers in a HttpModule

How do you set them up?

If I have the following code in a HttpModule.

public static event EventHandler<PostProcessingEventArgs> OnPostProcessing;

And in an async PostAuthorizeRequest task set up using EventHandlerTaskAsyncHelper.

// Fire the post processing event.
EventHandler<PostProcessingEventArgs> handler = OnPostProcessing;
if (handler != null)
{
    handler(this, new PostProcessingEventArgs { CachedPath = cachedPath });
}

And then tap into it using this.

ProcessingModule.OnPostProcessing += this.WritePath;    

private async void WritePath(object sender, PostProcessingEventArgs e)
{
    await Task.Factory.StartNew(() => Debug.WriteLine(e.CachedPath));
}

I get the following error.

An asynchronous module or handler completed while an asynchronous operation was still pending.

Edit

Ok so before I saw all these answers I got it to not throw the error by raising the event handler as follows.

EventHandlerTaskAsyncHelper postProcessHelper = 
new EventHandlerTaskAsyncHelper(this.PostProcessImage);

context.AddOnPostRequestHandlerExecuteAsync(postProcessHelper.BeginEventHandler,
postProcessHelper.EndEventHandler);

private Task PostProcessImage(object sender, EventArgs e)
{
    HttpContext context = ((HttpApplication)sender).Context;
    object cachedPathObject = context.Items[CachedPathKey];

    if (cachedPathObject != null)
    {
        string cachedPath = cachedPathObject.ToString();

        // Fire the post processing event.
        EventHandler<PostProcessingEventArgs> handler = OnPostProcessing;
        if (handler != null)
        {
            context.Items[CachedPathKey] = null;
            return Task.Run(() => handler(this, 
            new PostProcessingEventArgs { CachedImagePath = cachedPath }));
        }
    }

    return Task.FromResult<object>(null);
}

From what I can see below though this seems unwise.

The single purpose of this eventhandler would be to allow someone to run longer running tasks on the file like using something like jpegtran or pngout to post-process an image to further optimize it. What's the best approach for that?

like image 842
James South Avatar asked Aug 17 '14 10:08

James South


1 Answers

You can add async event handlers using the AddOn* methods in the HttpApplication class. I'm sure that async void methods are not supported by all of them. Maybe by none of them.

To use those methods despite the fact that they do not directly support tasks, you need to adapt your task to be compatible with the APM pattern which ASP.NET uses here.

Maybe it is just sample code but you use of Task.Factory.StartNew is not helpful in the context of a web application.

like image 197
usr Avatar answered Sep 23 '22 02:09

usr