Почему метод OnActionExecuted моего ActionFilterAttribute срабатывает до завершения асинхронной операции? - PullRequest
2 голосов
/ 05 января 2012

У меня есть фильтр действий 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 запускается, пока моя асинхронная работа еще выполняется, запрос базы данных в фоновом работнике не выполняется, поскольку сеанс уже закрыт.Как мне исправить это?

1 Ответ

0 голосов
/ 05 января 2012

Я понятия не имею, как 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();
    });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...