Skip to content

Instantly share code, notes, and snippets.

@dmitryvk
Created December 18, 2018 10:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dmitryvk/0e8f03e30f29f9525378d0f0f56b8f7a to your computer and use it in GitHub Desktop.
Save dmitryvk/0e8f03e30f29f9525378d0f0f56b8f7a to your computer and use it in GitHub Desktop.
Mono-async-EndRequest
namespace WebApplication2
{
using System;
using System.Threading.Tasks;
using System.Web;
public class MvcApplication : HttpApplication
{
public MvcApplication()
{
AuthenticateRequest += OnAuthenticateRequest ;
AddOnEndRequestAsync(OnBeginEndRequest, OnEndEndRequest);
}
private volatile bool isEnding = false;
private void OnAuthenticateRequest(object sender, EventArgs e)
{
if (isEnding)
{
throw new Exception("OnAuthenticateRequest: isEnding: expected false, got true");
}
}
private IAsyncResult OnBeginEndRequest(object sender, EventArgs e, AsyncCallback cb, object extradata)
{
Func<Task<object>> InnerFn = async () =>
{
await Task.Delay(TimeSpan.FromMilliseconds(1000));
isEnding = false;
return null;
};
isEnding = true;
return InnerFn().AsApm(cb, extradata);
}
private void OnEndEndRequest(IAsyncResult ar)
{
var r = ((Task<object>) ar).Result;
}
}
public static class Util
{
public static IAsyncResult AsApm<T>(this Task<T> task,
AsyncCallback callback,
object state)
{
if (task == null)
throw new ArgumentNullException("task");
var tcs = new TaskCompletionSource<T>(state);
task.ContinueWith(t =>
{
if (t.IsFaulted)
tcs.TrySetException(t.Exception.InnerExceptions);
else if (t.IsCanceled)
tcs.TrySetCanceled();
else
tcs.TrySetResult(t.Result);
if (callback != null)
callback(tcs.Task);
}, TaskScheduler.Default);
return tcs.Task;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment