簡體   English   中英

自定義操作過濾器中有待處理的異步任務?

[英]Asynchronous task pending in custom action filter?

我需要你的幫助! 我已經解決了好一陣子了,但我一直無法弄清楚。 假設我們有以下控制器:

class NotifierController : MyBaseController {
    ... 
    [HttpGet]
    [CanNotifyUser]
    public async Task<ActionResult> NotifyUser(string id)
    {
        return View(await DataBase.Users.FindAsync(id));
    }
    // More actions decorated with the CanNotifyUserAttribute attribute
}

DataBase是在MyBaseController定義的屬性,例如:

static ApplicationDbContext _appDbContext;
public ApplicationDbContext DataBase 
{ 
    get { return _appDbContext ?? (_appDbContext = new ApplicationDbContext()); } 
}

ApplicationDbContext繼承自IdentityDbContext<MyUser> ,其中MyUser繼承自IdentityUser 所以,我的問題(我認為)來自自定義操作過濾器CanNotifyUserAttribute ,其OnActionExecuting覆蓋定義為(刪除所有檢查以盡可能減少):

public override async void OnActionExecuting(ActionExecutingContext filterContext)
{
    NotifierController controller = filterContext.Controller as NotifierController;
    Boss boss = await controller.DataBase.Bosses.FindAsync(filterContext.HttpContext.User.Identity.GetUserId());
    object id = filterContext.ActionParameters["id"];
    User user = await controller.DataBase.Users.FindAsync(id.ToString());
    if (user.Department.Id != boss.Department.Id)
    {
        filterContext.Result = new RedirectToRouteResult(
            new RouteValueDictionary(
                new
                {
                    action = "Login",
                    controller = "Account",
                    returnUrl = controller.Url.Action("NotifyUser", new { id = id })
                }));
    }
    base.OnActionExecuting(filterContext);
}

具有此屬性的想法是驗證老板僅將通知發送給其部門的用戶。 現在出現了一個奇怪的部分,這僅在我第一次嘗試向用戶發送通知(無論它是否屬於同一部門)時發生,錯誤提示是:

[InvalidOperationException:異步模塊或處理程序在異步操作仍掛起時完成。

如果我嘗試(在錯誤之后)相同的請求(即通知用戶),則它可以像重定向或發送通知那樣擴展。

根據這篇文章,我可能會在異步任務完成之前完成請求(如果我理解得很好),但是我一直在使用的所有任務都在await因此我不知道此錯誤可能來自何處。 希望您能夠幫助我。 提前致謝!

您試圖通過將OnActionExecuting轉換為async void對過濾器實施異步行為。 asnyc void方法應僅在異步事件處理程序的上下文中使用,因為它們具有特殊的錯誤處理語義,並且調用過程“無法”等待在(filter-)方法體內執行的任務(以供進一步閱讀,考慮一下 Stephen Cleary撰寫的這篇很棒的文章)。

因此,對於ASP.NET Core,請考慮改為使用IAsyncActionFilter接口。

過濾器通過不同的接口定義支持同步和異步實現。 異步過濾器定義單個OnStageExecutionAsync方法。 此方法接受一個FilterTypeExecutionDelegate委托,該委托執行過濾器的管道階段。 ASP.NET Core中的篩選器

所以代替...

public override async void OnActionExecuting(ActionExecutingContext filterContext)

...采用:

public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)

有關如何使用此方法的更多說明,請參見: ASP.NET Core的ActionFilterAttribute中的Async OnActionExecuting

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM