2012-01-04 14 views
2

我有一個NHibernate的動作過濾器,設置了與會議的部署/交易,像這樣:爲什麼我的ActionFilterAttribute的OnActionExecuted方法在異步操作完成之前觸發?

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方法燒製,因爲會話已經關閉在後臺工作的數據庫查詢失敗。我將如何去解決這個問題?

+0

嗯......你真的應該創造一個背景工作?我還沒有使用AsyncController,但我只是假定它會爲您處理「異步」方面... – dotjoe 2012-01-04 20:07:56

+0

有幾種方法可以做到這一點。如果您使用某種服務或組件來提供自己的BeginWork和EndWork類型的方法,那麼您只需將它們掛鉤。由於我只是執行一個隨機代碼塊異步,我正在利用BackgroundWorker類來提供異步設施。 – Chris 2012-01-04 20:09:15

+0

哦,所以當你調用Increment()時,它應該阻塞,直到後臺工作者代碼調用Decrement()?另外,我不認爲ISession是線程安全的......那麼在這裏使用異步的點是什麼? – dotjoe 2012-01-04 20:26:18

回答

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(); 
    }); 
} 
+0

我只是試着用你的代碼,沒有骰子。由於ObjectDisposedException(「session closed!」),查詢仍然失敗。 – Chris 2012-01-04 20:28:05

+0

@克里斯有趣。你在SomeOperationAsync方法裏做了什麼嗎? – tugberk 2012-01-04 20:35:48

+0

不是。我猜這裏我的問題的根源是OnActionExecuted不是「異步」的意識。它在第一個方法結束後返回,而不是在AsyncManager執行Completed回調時返回。我不知道爲什麼,或者如何解決... – Chris 2012-01-04 20:41:41

相關問題