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

C#多Web流读取性能优化:Discord Bot加载过慢问题求助

优化Discord Bot中OSRS排行榜API调用的加载速度

你的命令加载慢的核心原因就是同步串行调用了4个OSRS排行榜接口——每个请求都要等前一个完全完成才会开始,网络延迟、服务器响应时间都会被累加,总耗时是4个请求的时间总和。下面是具体的优化方案和代码改进建议:

1. 核心优化:并行异步请求

用HttpClient的异步方法同时发起所有请求,通过Task.WhenAll等待全部完成,这样总耗时会接近最慢的那个请求的时间,而不是4个请求的时间相加。另外,HttpClient要复用,不要每次请求都创建新实例(频繁创建会耗尽TCP连接资源)。

2. 其他代码优化点

  • 提取重复的API请求逻辑成复用方法,减少冗余代码,方便后续维护
  • 不要吞掉所有异常,至少记录错误日志,方便排查请求失败的原因
  • 用long.TryParse代替Convert.ToInt64,避免格式错误导致的崩溃
  • 对player参数进行URL编码,防止特殊字符导致请求失败
  • 修复账号判断逻辑中的bug:原代码里Convert.ToInt64(UIMExp + HCExp)是把两个字符串拼接后转数字,逻辑错误,应该分别转数字后再相加

优化后的完整代码示例

// 建议把HttpClient作为Bot的全局实例,不要每次请求都创建
private static readonly HttpClient _httpClient = new HttpClient();

// 提取复用的API请求方法
private async Task<string> GetTotalExpAsync(string player, string hiscoreType)
{
    var encodedPlayer = Uri.EscapeDataString(player);
    var url = $"https://secure.runescape.com/m=hiscore_oldschool{hiscoreType}/index_lite.ws?player={encodedPlayer}";
    
    try
    {
        var response = await _httpClient.GetStringAsync(url);
        var lines = response.Split('\n');
        if (lines.Length > 0)
        {
            var totalParts = lines[0].Split(',');
            if (totalParts.Length >= 3)
            {
                return totalParts[2];
            }
        }
    }
    catch (Exception ex)
    {
        // 这里可以加日志记录,比如Console.WriteLine($"请求失败: {hiscoreType}, 错误: {ex.Message}");
    }
    return "0";
}

// 命令处理方法
public async Task HandleHiscoreCommand(string player)
{
    // 并行发起所有请求
    var normalTask = GetTotalExpAsync(player, "");
    var ironTask = GetTotalExpAsync(player, "_ironman");
    var hcTask = GetTotalExpAsync(player, "_hardcore_ironman");
    var uimTask = GetTotalExpAsync(player, "_ultimate");

    // 等待所有请求完成
    await Task.WhenAll(normalTask, ironTask, hcTask, uimTask);

    // 获取结果
    var normalExp = normalTask.Result;
    var ironExp = ironTask.Result;
    var hcExp = hcTask.Result;
    var uimExp = uimTask.Result;

    // 发送结果
    await ReplyAsync(
        $"**Normal: ** {normalExp}\n" +
        $"**Ironman: ** {ironExp}\n" +
        $"**Hardcore: ** {hcExp}\n" +
        $"**UIM: ** {uimExp}");

    // 修复后的账号判断逻辑
    if (long.TryParse(uimExp, out var uimNum) && long.TryParse(normalExp, out var normalNum) && uimNum == normalNum)
    {
        await ReplyAsync("Account is a UIM");
    }
    else if (long.TryParse(hcExp, out var hcNum) && hcNum == normalNum)
    {
        await ReplyAsync("Account is a HC");
    }
    else if (long.TryParse(ironExp, out var ironNum) && ironNum == normalNum)
    {
        var uimVal = long.TryParse(uimExp, out var u) ? u : 0;
        var hcVal = long.TryParse(hcExp, out var h) ? h : 0;
        if (ironNum > uimVal + hcVal)
        {
            if (uimVal > 1)
            {
                await ReplyAsync("Account is a ~~UIM~~ Normal Ironman");
            }
            else if (hcVal > 1)
            {
                await ReplyAsync("Account is a ~~HC~~ Normal Ironman");
            }
            else
            {
                await ReplyAsync("Account is a Normal Ironman");
            }
        }
    }
    else
    {
        var uimVal = long.TryParse(uimExp, out var u) ? u : 0;
        var ironVal = long.TryParse(ironExp, out var i) ? i : 0;
        var hcVal = long.TryParse(hcExp, out var h) ? h : 0;

        if (uimVal > 1 && ironVal > 1)
        {
            await ReplyAsync("Account is a ~~UIM~~, ~~Ironman~~, normal player.");
        }
        else if (hcVal > 1 && ironVal > 1)
        {
            await ReplyAsync("Account is a ~~HC~~, ~~Ironman~~, normal player.");
        }
        else if (ironVal > 1 && hcVal == 0 && uimVal == 0)
        {
            await ReplyAsync("Account is a ~~Ironman~~ normal player.");
        }
        else
        {
            await ReplyAsync("Account is a Normal Player");
        }
    }
}

额外建议

  • 可以加入缓存机制:如果同一个玩家短时间内再次查询,直接返回缓存结果,避免重复请求API
  • 检查OSRS的API是否有批量查询的接口,减少请求次数(不过目前OSRS的hiscore接口好像没有批量查询不同模式的功能)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 15:06:47