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

.NET 6类库中Service Bus发送方法执行异常排查

问题描述

将Service Bus消息发送方法提取到.NET 6类库后,调用该方法时,程序执行CreateMessageBatchAsync后无异常退出,后续代码断点无法触发。原代码在控制台应用中可正常运行。

原控制台应用代码

var cln= new ServiceBusClient(connectionString);
var sender = cln.CreateSender(topicName);
var body = JsonSerializer.Serialize(obj);
var message = new ServiceBusMessage(body)
{
    ContentType = "application/json"
};
try
{
    var batch = await sender.CreateMessageBatchAsync();

    var test = "123";

    if (!batch.TryAddMessage(message))
    {
        throw new Exception("Error occured while sending object to topic");
    }
    await sender.SendMessagesAsync(batch);
    await sender.DisposeAsync();
    await cln.DisposeAsync();
}
catch (Exception ex)
{
    Console.WriteLine($"Error sending message: {ex.Message}");
    throw;
}

迁移后的.NET 6类库方法代码

public async Task SendBatchMessageAsync(string connectionStr, string topic, ServiceBusMessage message, int maxRetries = 3)
{
    int attempt = 0;
    do
    {
        try
        {

            var _client = new ServiceBusClient(connectionString);
            var _sender = _client.CreateSender(topic);
            var serviceBusMessageBatch = await _sender.CreateMessageBatchAsync();
            if (!serviceBusMessageBatch.TryAddMessage(message))
            {
                throw new Exception("Error occured");
            }
            await _sender.SendMessagesAsync(serviceBusMessageBatch);
            await _sender.DisposeAsync();
            await _client.DisposeAsync();
        }
        catch (ServiceBusException ex) when (ex.Reason == ServiceBusFailureReason.MessagingEntityDisabled ||
        ex.Reason == ServiceBusFailureReason.MessagingEntityNotFound ||
        ex.Reason == ServiceBusFailureReason.ServiceTimeout ||
        ex.Reason == ServiceBusFailureReason.ServiceBusy)
        {

            _logger.Error($"Transient exception caught: {ex.Message}");
            attempt++;
            if (attempt >= maxRetries) throw; // Give up after maxRetries
            // Wait for a bit before retrying
            await Task.Delay(ComputeDelay(attempt));
        }
        catch (Exception ex)
        {
            _logger.Error($"Error sending message: {ex.Message}");
            throw;
        }
    } while (attempt < maxRetries);
}

问题排查与修复

1. 参数名不匹配

类库方法接收的参数是connectionStr,但代码中使用的是未定义的connectionString,这会直接引发未初始化变量的异常。如果调用方未正确等待异步任务,异常会被吞掉,导致程序无提示退出。

修复:将方法内的connectionString替换为connectionStr,确保使用传入的连接字符串。

2. 异步方法未被正确等待

如果调用SendBatchMessageAsync时未添加await,或者在非异步上下文(比如控制台Main方法)中未正确处理异步任务,主线程会提前结束,看起来像是执行到CreateMessageBatchAsync后就退出了。

修复:调用方法时必须添加await;如果是控制台应用,将Main方法改为async Task Main,再用await调用发送方法。

3. 资源管理不合理

原类库代码每次重试都会创建新的ServiceBusClient和ServiceBusSender,频繁创建销毁会影响性能,且可能因异步释放问题引发隐藏异常。ServiceBusClient是线程安全的,建议作为单例复用。

优化后的示例代码:

// 通过依赖注入注入单例ServiceBusClient和Logger
private readonly ServiceBusClient _client;
private readonly ILogger _logger;

public ServiceBusSenderService(ServiceBusClient client, ILogger logger)
{
    _client = client;
    _logger = logger;
}

public async Task SendBatchMessageAsync(string topic, ServiceBusMessage message, int maxRetries = 3)
{
    int attempt = 0;
    var sender = _client.CreateSender(topic);
    try
    {
        do
        {
            try
            {
                var batch = await sender.CreateMessageBatchAsync();
                if (!batch.TryAddMessage(message))
                {
                    throw new Exception("消息过大无法加入批次");
                }
                await sender.SendMessagesAsync(batch);
                return;
            }
            catch (ServiceBusException ex) when (ex.Reason is ServiceBusFailureReason.MessagingEntityDisabled or 
                ServiceBusFailureReason.MessagingEntityNotFound or 
                ServiceBusFailureReason.ServiceTimeout or 
                ServiceBusFailureReason.ServiceBusy)
            {
                _logger.Error($"捕获到临时异常: {ex.Message}");
                attempt++;
                if (attempt >= maxRetries) throw;
                await Task.Delay(ComputeDelay(attempt));
            }
            catch (Exception ex)
            {
                _logger.Error($"发送消息出错: {ex.Message}");
                throw;
            }
        } while (attempt < maxRetries);
    }
    finally
    {
        await sender.DisposeAsync();
    }
}

内容的提问来源于stack exchange,提问作者katie77

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 06:55:10