为什么我的ActionFilterAttribute的OnActionExecuted方法在异步操作完成之前触发?

时间:2012-01-04 20:02:38

标签: asp.net-mvc asp.net-mvc-3 asynchronous

我有一个NHibernate动作过滤器来设置和处理会话/事务,如下所示:

public class NHibernateActionAttribute : ActionFilterAttribute
{
    public ISessionFactory SessionFactory { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // inject nhibernate session into controller 
        // and start transaction
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        // commit or rollback and dispose
    }
}

事件在同步操作方法上触发很好,但是当我有一个异步操作(例如下面的那个)时,一旦第一个异步方法返回,动作过滤器的OnActionExecuted方法就会触发。

public void SomeOperationAsync(term) 
{
    object results = null
    var worker = new BackgroundWorker();

    worker.DoWork += (o,e) =>
    {
        // Do some lengthy DB query
        AsyncManager.Parameters["result"] = results;
        AsyncManager.OutstandingOperations.Decrement();
    };

    AsyncManager.OutstandingOperations.Increment();
    worker.RunWorkerAsync();        
    // OnActionExecuted fires NOW.
}

public ActionResult SomeOperationCompleted(object result) 
{
    return Json(result, JsonRequestBehavior.AllowGet);
    // I would expect OnActionExecuted to fire NOW.
}

问题是,由于OnActionExecuted方法在我的异步工作仍在进行时触发,后台工作程序中的db查询失败,因为会话已经关闭。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

我不知道BackgroundWorker在ASP.NET环境中的行为如何,但您可以使用Task类。试试下面的一个:

public void SomeOperationAsync(term) {

    AsyncManager.OutstandingOperations.Increment();

    Task<object>.Factory.StartNew(() => {

        object results = null

        // Do some lengthy DB query

        return results;

    }).ContinueWith(t => {

        AsyncManager.Parameters["result"] = t.Result;
        AsyncManager.OutstandingOperations.Decrement();
    });
}