使用Task.Factory.StartNew时不会触发ExceptionFilterAttribute

时间:2017-09-06 14:24:42

标签: c# asp.net asp.net-web-api

我正在开发一个ASP.NET Web API,在我的一个控制器操作中,我使用了Task.Factory.StartNew调用。

但是,这不会触发我在任务中抛出异常时配置的异常过滤器。

Controller.cs

public class MyController : ApiController
{
    [HttpPost]
    public HttpResponseMessage Post()
    {
        Task.Factory
            .StartNew(() => DoTheThing())
            .ContinueWith(tsk => { throw new Exception("Webhook Exception", tsk.Exception); }, TaskContinuationOptions.OnlyOnFaulted);

        return new HttpResponseMessage(HttpStatusCode.OK);
    }
}

ExceptionFilter.cs

public class ExceptionFilter : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext context)
    {
        throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError)
        {
            Content = new ObjectContent(typeof(object), new
            {
                Message = "Critical Error",
                ExceptionMessage = "An error occurred, please try again or contact the administrator.",
                Type = ExceptionType.Unhandled
            }, new JsonMediaTypeFormatter()),
            ReasonPhrase = "Critical Error"
        });
    }
}

的Global.asax.cs

public class MyApplication : HttpApplication
{
    protected void Application_Start()
    {            
        GlobalConfiguration.Configuration.Filters.Add(new ExceptionFilter());
    }
}

我可以调试并触发ContinueWith方法并抛出新的Exception。但是没有触发过滤器。

1 个答案:

答案 0 :(得分:2)

未触发过滤器,因为在与控制器操作方法线程不同的线程中抛出异常。你可以:

  1. 等待任务

    [HttpPost]
    public async Task<HttpResponseMessage> Post()
    {
        await Task.Factory
            .StartNew(() => DoTheThing())
            .ContinueWith(tsk => { throw new Exception("Webhook Exception", tsk.Exception); }, TaskContinuationOptions.OnlyOnFaulted);
    
        return new HttpResponseMessage(HttpStatusCode.OK);
    }
    
  2. 等待任务

    [HttpPost]
    public HttpResponseMessage Post()
    {
        var task = Task.Factory
                       .StartNew(() => DoTheThing())
                       .ContinueWith(tsk => { throw new Exception("Webhook Exception", tsk.Exception); }, TaskContinuationOptions.OnlyOnFaulted);
    
        task.Wait();
    
        return new HttpResponseMessage(HttpStatusCode.OK);
    }
    
  3. 所有这些方法都会在操作方法中重新抛出异常,并且过滤器会抓住它。