gpt4 book ai didi

c# - 使用 Task.Run 而不是 Delegate.BeginInvoke

转载 作者:太空狗 更新时间:2023-10-29 19:52:24 25 4
gpt4 key购买 nike

我最近将我的项目升级到 ASP.NET 4.5,我已经等待了很长时间才能使用 4.5 的异步功能。阅读文档后,我不确定是否可以改进我的代码。

我想异步执行一个任务然后忘记它。我目前这样做的方法是创建委托(delegate),然后使用 BeginInvoke

这是我项目中的一个过滤器,每当用户访问必须审核的资源时,它就会在我们的数据库中创建一个审核:

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var request = filterContext.HttpContext.Request;
var id = WebSecurity.CurrentUserId;

var invoker = new MethodInvoker(delegate
{
var audit = new Audit
{
Id = Guid.NewGuid(),
IPAddress = request.UserHostAddress,
UserId = id,
Resource = request.RawUrl,
Timestamp = DateTime.UtcNow
};

var database = (new NinjectBinder()).Kernel.Get<IDatabaseWorker>();
database.Audits.InsertOrUpdate(audit);
database.Save();
});

invoker.BeginInvoke(StopAsynchronousMethod, invoker);

base.OnActionExecuting(filterContext);
}

但是为了完成这个异步任务,我总是需要定义一个回调,它看起来像这样:

public void StopAsynchronousMethod(IAsyncResult result)
{
var state = (MethodInvoker)result.AsyncState;
try
{
state.EndInvoke(result);
}
catch (Exception e)
{
var username = WebSecurity.CurrentUserName;
Debugging.DispatchExceptionEmail(e, username);
}
}

我宁愿根本不使用回调,因为我不需要异步调用的任务的结果。

如何使用 Task.Run()(或 asyncawait)改进此代码?

最佳答案

如果我正确理解了您的要求,您想开始一项任务然后忘记它。当任务完成时,如果发生异常,您希望将其记录下来。

我会使用 Task.Run 创建任务,然后使用 ContinueWith 附加一个延续任务。此延续任务将记录从父任务抛出的任何异常。此外,使用 TaskContinuationOptions.OnlyOnFaulted 确保延续仅在 发生异常时运行。

Task.Run(() => {
var audit = new Audit
{
Id = Guid.NewGuid(),
IPAddress = request.UserHostAddress,
UserId = id,
Resource = request.RawUrl,
Timestamp = DateTime.UtcNow
};

var database = (new NinjectBinder()).Kernel.Get<IDatabaseWorker>();
database.Audits.InsertOrUpdate(audit);
database.Save();

}).ContinueWith(task => {
task.Exception.Handle(ex => {
var username = WebSecurity.CurrentUserName;
Debugging.DispatchExceptionEmail(ex, username);
});

}, TaskContinuationOptions.OnlyOnFaulted);

作为旁注,强烈不鼓励 ASP.NET 中的后台任务和即发即弃方案。参见 The Dangers of Implementing Recurring Background Tasks In ASP.NET

关于c# - 使用 Task.Run 而不是 Delegate.BeginInvoke,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22686467/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com