我需要在Global.asax中调用我的数据库上的一些异步操作。 例如,在Application_AuthenticateRequest中,我需要针对DB对用户进行身份验证 是否可以使用异步任务?
答案 0 :(得分:24)
现在有一种更简单的方法:
public MvcApplication()
{
var wrapper = new EventHandlerTaskAsyncHelper(DoAsyncWork);
this.AddOnAuthenticateRequestAsync(wrapper.BeginEventHandler, wrapper.EndEventHandler);
}
private async Task DoAsyncWork(object sender, EventArgs e)
{
var app = (HttpApplication)sender;
var ctx = app.Context;
...
await doSomethingAsync();
}
使用这种方法,您可以使用async关键字定义一个方法,并使用'EventHandlerTaskAsyncHelper'类包装该方法,以生成BeginEventHandler和EndEventHandler方法,以传递给AddOnAuthenticateRequestAsync调用。
答案 1 :(得分:2)
我没有找到使用新的C#关键字async和await的方法,但我们仍然可以使用APM模式在Global.asax中使用异步操作,因为它实现了IHttpAsyncHandler接口。这是一个演示异步的小代码,这里我以WebRequst为例,在你的情况下请使用数据库操作。
public Global()
{
this.AddOnAuthenticateRequestAsync(BeginGetAsyncData, EndGetAsyncData);
}
IAsyncResult BeginGetAsyncData(Object src, EventArgs args, AsyncCallback cb, Object state)
{
Console.WriteLine("BeginGetAsyncData: thread #" + System.Threading.Thread.CurrentThread.ManagedThreadId);
WebRequest request = WebRequest.Create("http://www.google.com");
return request.BeginGetResponse(cb, request); // call database async operation like SqlCommand.BeginExecuteReader()
}
void EndGetAsyncData(IAsyncResult ar)
{
Console.WriteLine("EndGetAsyncData: thread #" + System.Threading.Thread.CurrentThread.ManagedThreadId);
WebRequest requst = (WebRequest)ar.AsyncState;
System.Net.WebResponse response = requst.EndGetResponse(ar); // call database async operation like SqlCommand.EndExecuteReader()
Console.WriteLine(new StreamReader(response.GetResponseStream()).ReadToEnd());
response.Close();
}
答案 2 :(得分:1)
您必须自己添加AuthenticateRequest的异步版本。使用以下代码:
public MvcApplication()
{
// Contrary to popular belief, this is called multiple times, one for each 'pipeline' created to handle a request.
// Wire up the async authenticate request handler.
AddOnAuthenticateRequestAsync(BeginAuthenticateRequest, EndAuthenticateRequest, null);
}
问题是,如何使用C#的新async / await功能实现BeginAuthenticateRequest
和EndAuthenticateRequest
。首先,让我们将AuthenticateRequest的异步版本放在一边:
private async Task AuthenticateRequestAsync(object sender, EventArgs args)
{
// Yay, let's do async stuff!
await ...
}
我们接下来需要做的是提出BeginAuthenticateRequest和EndAuthenticateRequest的实现。我跟着a blog post,但得到了我自己的实现:
private IAsyncResult BeginAuthenticateRequest(object sender, EventArgs args, AsyncCallback callback, object state)
{
Task task = AuthenticateRequestAsync(sender, args);
var tcs = new TaskCompletionSource<bool>(state);
task.ContinueWith(_ =>
{
if (task.IsFaulted && task.Exception != null) tcs.TrySetException(task.Exception.InnerExceptions);
else if (task.IsCanceled) tcs.TrySetCanceled();
else tcs.TrySetResult(true);
if (callback != null) callback(tcs.Task);
}, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Default);
return tcs.Task;
}
您可以阅读整篇链接文章以了解其工作原理,但基本上IAsyncResult
由Task实现,因此您只需在完成后调用回调。
最后一点很简单:
private void EndAuthenticateRequest(IAsyncResult result)
{
// Nothing to do here.
}