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

Windows服务中调用Telegram Bot静态布尔方法出现冻结无响应问题

问题:Windows服务调用静态布尔方法导致冻结,WinForms中运行正常

在Windows服务中调用静态布尔方法IsUserRegistered时,服务会冻结且无法处理任何请求;但该方法在WinForms应用中可正常执行,注释掉该方法调用后服务恢复正常,且服务内其他读取注册表的操作均无异常。怀疑是否JSON在异步方法中无法工作?

静态布尔方法代码

public static bool IsUserRegistered(long UserId)
{
    List<TelegramUser> UserDb = new List<TelegramUser>();
    string json = System.IO.File.ReadAllText(GlobalStrings.File_UserDB);
    UserDb = JsonSerializer.Deserialize<List<TelegramUser>>(json);
    TelegramUser selectedUser = UserDb.Find(u => u.ChatID == UserId);
    return selectedUser != null;
}

Windows服务调用代码

static async Task OnMessage(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken)
{
    bool UserOrGuest = false;
    if (update.Message is Message message)
    {
        UserOrGuest = Users.IsUserRegistered(6122562837);
        SendMessage(update.Message, "Registered: "+ UserOrGuest.ToString());
    }
}

原因分析与解决方案

问题并非JSON在异步方法中无法工作,核心原因是Windows服务的运行权限与文件路径不匹配:

  • Windows服务默认以Local System账户运行,该账户对用户专属目录(如C:\Users\XXX\...)无访问权限,若GlobalStrings.File_UserDB指向此类路径,服务会因权限不足卡在File.ReadAllText步骤,导致线程阻塞、服务冻结。
  • 若使用相对路径,服务会默认读取系统目录(如C:\Windows\System32),而非程序安装目录,引发文件找不到的问题,进而阻塞服务。

解决步骤

  1. 修正文件路径
    确保GlobalStrings.File_UserDB指向服务有权访问的路径,比如程序安装目录或公共数据目录:

    // 获取服务程序的运行目录
    string appDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
    GlobalStrings.File_UserDB = Path.Combine(appDir, "userdb.json");
    

    或使用公共数据目录:Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "你的应用名", "userdb.json")

  2. 配置服务权限

    • 若必须使用特定路径,可修改服务的登录账户为拥有该路径访问权限的本地用户;
    • 或给Local System账户添加目标文件/文件夹的读取权限。
  3. 添加异常捕获
    在IsUserRegistered中加入异常处理,避免未处理异常导致服务阻塞,同时记录错误日志:

    public static bool IsUserRegistered(long UserId)
    {
        try
        {
            List<TelegramUser> UserDb = new List<TelegramUser>();
            string json = System.IO.File.ReadAllText(GlobalStrings.File_UserDB);
            UserDb = JsonSerializer.Deserialize<List<TelegramUser>>(json);
            return UserDb.Any(u => u.ChatID == UserId);
        }
        catch (Exception ex)
        {
            // 写入Windows事件日志
            EventLog.WriteEntry("你的服务名称", $"IsUserRegistered错误:{ex.Message}", EventLogEntryType.Error);
            return false;
        }
    }
    
  4. 改用异步IO避免线程阻塞
    将同步文件读取改为异步方法,避免在异步回调中阻塞线程池:

    public static async Task<bool> IsUserRegisteredAsync(long UserId)
    {
        try
        {
            string json = await System.IO.File.ReadAllTextAsync(GlobalStrings.File_UserDB);
            List<TelegramUser> UserDb = JsonSerializer.Deserialize<List<TelegramUser>>(json);
            return UserDb.Any(u => u.ChatID == UserId);
        }
        catch (Exception ex)
        {
            EventLog.WriteEntry("你的服务名称", $"IsUserRegisteredAsync错误:{ex.Message}", EventLogEntryType.Error);
            return false;
        }
    }
    

    调用时同步改为异步:

    UserOrGuest = await Users.IsUserRegisteredAsync(6122562837);
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 05:35:40