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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With