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

WTelegram.Client释放后仍占用session文件,重连失败求助

问题诊断与修复方案

核心问题分析

  • 递归调用引发多实例竞争:Login_do异常捕获中递归调用Login_start(),导致多个WTelegram.Client实例创建流程并行执行。即便Dispose当前实例,递归生成的新实例可能在旧实例文件锁未完全释放时就尝试打开session文件,触发占用冲突。
  • Dispose后资源释放延迟:Dispose()调用后,.NET垃圾回收不会立即执行,文件句柄可能仍被系统占用,此时立刻创建新实例会触发文件访问错误。

修复步骤

1. 移除递归调用,统一重试逻辑

将登录重试逻辑集中到外层循环,避免嵌套递归导致的多实例竞争。让Login_do仅负责单次登录尝试,失败后将控制权交还给Login_start处理重试。

2. 确保Dispose后资源彻底释放

Dispose client后,主动触发垃圾回收(此场景下可强制释放文件句柄),或增加短暂延迟让系统完成资源释放。

修改后的代码示例

public async Task Login_start()
{
    while (true)
    {
        try
        {
            cG.print_inlog($"Connecting & login into Telegram servers...");
            // 确保新实例创建前,旧实例已被释放
            client?.Dispose();
            client = new WTelegram.Client(int.Parse(Config_func("api_id")), Config_func("api_hash"));

            var loginResult = await Login_do(Config_func("phone_number"));
            if (loginResult == null) // 登录成功,退出循环
                break;
            
            // 此处可补充验证码等额外验证逻辑
        }
        catch (Exception ex)
        {
            cG.print_inlog($"Login failed: {ex.Message}");
            client?.Dispose();
            client = null;
            // 强制触发垃圾回收,确保文件句柄释放
            GC.Collect();
            GC.WaitForPendingFinalizers();
            await Task.Delay(5000);
        }
    }
}

public async Task<string?> Login_do(string loginInfo)
{
    try
    {
        cG.print_inlog($"connecting...");
        var what = await client.Login(loginInfo);
        if (what == null)
        {
            cG.print_inlog($"We are now connected as {client.User}");
            // 复用client执行后续业务操作
            var chs = (await client.Messages_GetAllChats()).chats;
        }
        return what;
    }
    catch (Exception ex)
    {
        cG.print_inlog($"Login attempt failed: {ex.Message}");
        throw; // 将异常抛回外层,由Login_start统一处理重试
    }
}

额外优化建议

  • 减少Client实例销毁:若仅为网络连接失败,无需完全销毁Client,可尝试client.Reset(false, true)重置连接状态(保留session),减少文件操作次数,降低锁冲突概率。
  • 自定义session路径:创建Client时指定唯一session文件路径,避免默认路径下的文件竞争:
    client = new WTelegram.Client(apiId, apiHash, sessionPath: Path.Combine(Path.GetTempPath(), "MyApp_Telegram.session"));
    

内容的提问来源于stack exchange,提问作者Tecnosoft-dev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 04:12:17