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

如何关闭Swagger时调用TCP连接类Dispose方法清理套接字

解决Swagger终止微服务时TCP类Dispose未触发的问题

1. 先规范IDisposable实现

确保你的TCP类正确实现IDisposable模式,覆盖托管/非托管资源的清理,避免套接字残留:

public class TcpConnection : IDisposable
{
    private Socket _socket;
    private bool _disposed;

    // 业务逻辑代码

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (_disposed) return;

        if (disposing)
        {
            // 先关闭套接字的收发通道
            _socket?.Shutdown(SocketShutdown.Both);
        }

        // 强制关闭套接字,释放底层资源
        _socket?.Close();
        _socket = null;

        _disposed = true;
    }

    ~TcpConnection() => Dispose(false);
}

2. 绑定ASP.NET Core应用生命周期钩子

微服务基于ASP.NET Core托管时,通过应用生命周期事件主动触发Dispose,覆盖Swagger窗口关闭的场景:

方式一:注册ApplicationStopping回调

在Program.cs中注入IHostApplicationLifetime,监听应用停止信号:

var builder = WebApplication.CreateBuilder(args);

// 注册你的TCP类为单例/作用域服务
builder.Services.AddSingleton<TcpConnection>();

var app = builder.Build();

var lifetime = app.Services.GetRequiredService<IHostApplicationLifetime>();
var tcpConn = app.Services.GetRequiredService<TcpConnection>();

// 应用停止前触发Dispose
lifetime.ApplicationStopping.Register(() => tcpConn.Dispose());

// Swagger配置
app.UseSwagger();
app.UseSwaggerUI();

app.Run();

方式二:封装为IHostedService

如果TCP类需要长期维持连接,包装成IHostedService,让主机自动管理启停:

public class TcpHostedService : IHostedService, IDisposable
{
    private readonly TcpConnection _tcpConn;

    public TcpHostedService(TcpConnection tcpConn)
    {
        _tcpConn = tcpConn;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        // 初始化TCP连接逻辑
        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        // 应用停止时自动调用Dispose
        _tcpConn.Dispose();
        return Task.CompletedTask;
    }

    public void Dispose() => _tcpConn.Dispose();
}

然后在Program.cs中注册托管服务:

builder.Services.AddHostedService<TcpHostedService>();
builder.Services.AddSingleton<TcpConnection>();

3. 处理强制终止场景

如果关闭Swagger窗口是直接杀死进程(比如任务管理器结束进程),托管代码的清理逻辑无法执行,此时依赖TCP套接字的系统级配置:

// 在Socket初始化时设置SO_LINGER选项
var lingerOpt = new LingerOption(true, 5); // 5秒超时
_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, lingerOpt);

开启该选项后,进程终止时操作系统会在超时时间内主动发送FIN包,强制关闭连接,减少ESTABLISHED状态的残留。

4. 局部实例用using包裹

如果TCP类是业务方法中的局部实例,必须用using语句确保即时释放:

using(var tcpConn = new TcpConnection())
{
    // 执行TCP通信逻辑
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 05:25:21