我开始使用WebJobs来处理一些后台任务,我遇到了有关错误处理和重试的问题。看来,如果我的任何函数都是异步的,那么即使我在函数中抛出异常,该函数也总是在仪表板中报告成功。
考虑以下简单示例 - >
public static void AlwaysFail([QueueTrigger("alwaysfail")] string message)
{
throw new Exception("Induced Error");
}
上面的代码表现得像我期望的那样。消息从队列中弹出,抛出异常,在WebJobs仪表板中报告失败,消息被重新排队。这种情况发生了5次,然后消息存储在毒药队列中。
但是,如果我尝试类似的功能,但使其像下面的那样异步 - >
public async static void AlwaysFail([QueueTrigger("alwaysfail")] string message)
{
throw new Exception("Induced Error");
}
结果与预期不符。消息从队列中弹出,抛出异常,但仪表板报告成功,不重试任何内容。此外,在这些情况下,似乎虽然仪表板报告成功,但异常是使用此世界退出代码中的进程崩溃,等待60秒,然后重新启动,如以下日志中所示 - >
[11/11/2014 06:13:35> 0dc4f9:INFO]正在执行:' Functions.AlwaysFail'因为在' alwaysfail'上检测到新的队列消息。 [11/11/2014 06:13:36> 0dc4f9:ERR] [11/11/2014 06:13:36> 0dc4f9:ERR]未处理的异常:System.InvalidOperationException:诱导错误 [11/11/2014 06:13:36>在Plmtc.BackgroundWorker.Functions.d__2.MoveNext()的0dc4f9:ERR] [11/11/2014 06:13:36> 0dc4f9:ERR] ---从抛出异常的上一个位置开始的堆栈跟踪结束--- [11/11/2014 06:13:36> System.Runtime.CompilerServices.AsyncMethodBuilderCore.b__5(对象状态)中的0dc4f9:ERR] [11/11/2014 06:13:36> System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(对象状态)中的0dc4f9:ERR] [11/11/2014 06:13:36> System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean preserveSyncCtx)中的0dc4f9:ERR] [11/11/2014 06:13:36> System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean preserveSyncCtx)中的0dc4f9:ERR] [11/11/2014 06:13:36> System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()中的0dc4f9:ERR] [11/11/2014 06:13:36> System.Threading.ThreadPoolWorkQueue.Dispatch()中的0dc4f9:ERR] [11/11/2014 06:13:36> System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()中的0dc4f9:ERR] [11/11/2014 06:13:36> 0dc4f9:SYS ERR]由于退出代码-532462766,作业失败 [11/11/2014 06:13:36> 0dc4f9:SYS INFO]进程停止,等待60秒 [11/11/2014 06:13:36> 0dc4f9:SYS INFO]状态已更改为PendingRestart
我可以让仪表板中的异步函数失败,以编写一个将POCO类作为参数但只在消息中包含一个简单字符串的方法。在这些情况下,在到达任何函数代码之前,在消息/参数绑定期间发生故障。
有没有成功使用异步函数来响应队列触发器而没有这些问题的人?
答案 0 :(得分:10)
由于方法为async void
,因此WebJobs SDK无法等待方法完成。将其更改为返回Task
...
public async static Task AlwaysFail([QueueTrigger("alwaysfail")] string message)
{
throw new Exception("Induced Error");
}
有关详细信息,请参阅this post。