You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#异步责任链模式的异常处理问题:如何在注册类中捕获处理器抛出的异常

C#异步责任链模式的异常处理问题:如何在注册类中捕获处理器抛出的异常

嘿,我来帮你搞定这个异常捕获的问题!你现在遇到的情况,主要是因为异步责任链里的异步操作没有被正确等待,还有一个小笔误导致的问题,咱们一步步来解决:

问题根源分析

  1. 异步调用未等待:你的基类Handler<T>的Handle方法里,调用Next?.Handle(request)时没有用await。因为Handle是async Task方法,不等待的话,这个异步操作会变成“执行后不管”的状态,抛出的异常会在后台线程中逃逸,根本传不到Register方法的try/catch块里。
  2. 子类中的笔误:OnlyAdultValidationHandler里有一行多余的throw new Exception();,这会直接抛出异常,而且同样因为上面的等待问题,无法被捕获。

解决方案步骤

第一步:修复基类的异步等待逻辑

修改基类Handler<T>的Handle方法,给下一个处理器的调用加上await,确保异步操作的异常能正常传播:

using System.Threading.Tasks;

namespace Chain.Of.Responsibility.Example.Chain.Pattern
{
    public abstract class Handler<T> : IHandler<T>
    {
        private IHandler<T> Next { get; set; }

        public virtual async Task Handle(T request)
        {
            // 必须等待下一个处理器的异步操作,否则异常会逃逸
            await Next?.Handle(request);
        }

        public IHandler<T> SetNext(IHandler<T> next)
        {
            Next = next;
            return Next;
        }
    }

    // 确保IHandler<T>接口定义正确
    public interface IHandler<T>
    {
        Task Handle(T request);
    }
}

第二步:修复子类中的调用和笔误

每个子类在调用base.Handle(user)时也需要加await,同时删掉OnlyAdultValidationHandler里多余的throw语句:

修改后的UsernameRequiredValidationHandler
using System;
using System.Threading.Tasks;

namespace Chain.Of.Responsibility.Example.Chain.Pattern
{
    public class UsernameRequiredValidationHandler : Handler<User>
    {
        public override async Task Handle(User user)
        {
            if (string.IsNullOrWhiteSpace(user.Username))
            {
                throw new Exception("Username is required.");
            }
            // 等待基类的异步处理(即下一个处理器)
            await base.Handle(user);
        }
    }
}
修改后的PasswordRequiredValidationHandler
using System;
using System.Threading.Tasks;

namespace Chain.Of.Responsibility.Example.Chain.Pattern
{
    public class PasswordRequiredValidationHandler : Handler<User>
    {
        public override async Task Handle(User user)
        {
            if (string.IsNullOrWhiteSpace(user.Password))
            {
                throw new Exception("Password is required.");
            }
            await base.Handle(user);
        }
    }
}
修改后的OnlyAdultValidationHandler
using System;
using System.Threading.Tasks;

namespace Chain.Of.Responsibility.Example.Chain.Pattern
{
    public class OnlyAdultValidationHandler : Handler<User>
    {
        public override async Task Handle(User user)
        {
            // 删掉多余的throw语句
            if (user.BirthDate.Year > DateTime.Now.Year - 18)
            {
                throw new Exception("Age under 18 is not allowed.");
            }
            await base.Handle(user);
        }
    }
}

第三步:验证注册类的异常捕获

你的ChainPatternRegistrationProcessor代码不需要修改,因为已经用了await handler.Handle(user);,现在所有处理器抛出的异常都会被正确传播到try/catch块中,你会在控制台看到异常信息,并且可以正常处理。

关键总结

  • 所有async Task方法的调用都必须用await,否则异常会逃逸到后台线程,无法被上层捕获。
  • 异步责任链的每个节点都要确保等待下一个节点的异步操作,这样异常才能沿着链条向上传播。
  • 检查代码中的笔误,避免不必要的异常抛出。

备注:内容来源于stack exchange,提问作者Masoud H

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 09:30:30