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

C#中TwitchLib改为带返回值方法后仅执行一次问题

TwitchLib事件仅触发一次问题排查与解决

问题现象

原程序依赖全局变量和无返回值的public void方法,改为带返回值的private static方法后,TwitchLib的globalChatMessageReceived事件仅执行一次,后续无响应。程序仍在运行且能保存数据,但不再触发该消息接收事件。

前后代码对比

正常运行的无返回值实现

调用方式:

FindPokemonName(MessageSplitForPokemonName[1]);

FindTrainerID方法实现:

public void FindTrainerID(string TrainerID, string ChatDisplayName)
{
    TrainerVorhanden = false;
    if (File.Exists(@"C:\txt\trainer\" + TrainerID + ".txt"))
    {
        string FoundTrainer = File.ReadAllText(@"C:\txt\trainer\" + TrainerID + ".txt");
        Trainer = FoundTrainer.Split('\\');
        TrainerVorhanden = true;
    }
}

出现问题的带返回值实现

调用方式:

(string[] PokedexName, Boolean ChosenPokemonIsAvailable, Boolean ChosenPokemonIsNoStarter, string NameOfChosenPokemon) = FindPokemonName(MessageSplitForPokemonName[1]);

FindTrainerID方法实现:

private static (string[] Trainer, bool TrainerAvailable) FindTrainerID(string TrainerID)
{
    string[] Trainer = new string[5];
    Boolean TrainerAvailable = false;
    if (File.Exists(@"C:\txt\trainer\" + TrainerID + ".txt"))
    {
        string FoundTrainer = File.ReadAllText(@"C:\txt\trainer\" + TrainerID + ".txt");
        Trainer = FoundTrainer.Split('\\');
        TrainerAvailable = true;
    }
    return (Trainer, TrainerAvailable);
}

排查方向与解决方案

  1. 同步IO阻塞事件线程
    静态方法中的File.ReadAllText是同步IO操作,会阻塞TwitchLib的事件处理线程,导致后续消息无法被监听。
    解决:改用异步文件读取方法,避免阻塞线程:

    private static async Task<(string[] Trainer, bool TrainerAvailable)> FindTrainerID(string TrainerID)
    {
        string[] Trainer = new string[5];
        bool TrainerAvailable = false;
        if (File.Exists(@"C:\txt\trainer\" + TrainerID + ".txt"))
        {
            string FoundTrainer = await File.ReadAllTextAsync(@"C:\txt\trainer\" + TrainerID + ".txt");
            Trainer = FoundTrainer.Split('\\');
            TrainerAvailable = true;
        }
        return (Trainer, TrainerAvailable);
    }
    

    同时在事件处理方法中使用await调用该异步方法。

  2. 静默异常中断流程
    静态方法内部若发生未捕获的异常,会直接中断事件处理流程,但不会导致程序崩溃,表现为事件不再触发。
    解决:在globalChatMessageReceived事件处理方法中添加全局异常捕获,输出异常信息定位问题:

    private async void GlobalChatMessageReceived(object sender, ChatMessageReceivedArgs e)
    {
        try
        {
            // 原事件处理逻辑,包括调用静态方法的代码
            var result = await FindTrainerID(e.ChatMessage.Message);
            // 处理返回结果
        }
        catch (Exception ex)
        {
            Console.WriteLine($"事件处理出错:{ex.Message}\n{ex.StackTrace}");
            // 或写入日志文件留存记录
        }
    }
    
  3. 资源未释放导致后续操作失败
    若静态方法中存在未正确释放的资源(如文件流),可能导致后续文件操作无法执行,间接影响事件处理。
    解决:涉及流操作时使用using语句自动释放资源,确保每次操作后资源都被正确回收。

  4. 事件订阅意外失效
    检查代码中是否因变量作用域变更、静态方法的副作用,导致globalChatMessageReceived事件的订阅被取消。
    解决:确认事件订阅逻辑未被修改,确保订阅语句只执行一次且订阅对象未被垃圾回收。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 21:23:20