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

C#使用RestSharp异步请求图片保存时随机失败、文件损坏问题求助

你的问题同时存在async/await使用不当和服务端限流两方面原因,代码里的问题放大了服务端限流的影响,具体问题和修复方案如下:

代码存在的核心问题

1. 并发控制完全失效

你现在的分批逻辑是完全无效的:Task.Run() 调用的瞬间任务就已经开始执行,你先把所有请求对应的Task全部创建启动,之后再分批等待,等于程序启动瞬间所有请求就全部发向服务端,并发量根本不受3的限制,直接触发服务端限流规则,出现大量500、502、超时错误。

2. 异步逻辑中误用同步阻塞

GenerateFromSeed 方法中用 Thread.Sleep() 做延迟,会阻塞线程池线程,不仅浪费线程资源,还会打乱异步调度逻辑,导致请求超时概率升高,应该替换为 await Task.Delay()。

3. RestClient实例创建不当

每次请求都新建 RestClient 实例会导致套接字资源被快速耗尽,出现大量状态码0的超时错误,RestSharp官方推荐整个应用生命周期共用一个单例的RestClient实例。

4. Random线程不安全

Random 类本身不是线程安全的,你在多线程并发的 GenerateFromSeed 方法中调用 random.Next(),会损坏Random的内部状态,轻则返回异常值,重则抛出未捕获的异常,这也是 GenerateSeed 经常返回0的核心原因。

5. 缺少返回内容校验

你仅判断HTTP状态码为200就直接将返回内容存为jpg,当服务端返回的是500/502的错误页面但状态码异常时,会直接把HTML内容存为jpg文件,表现为文件损坏。

服务端侧的问题

libraryofbabel.info 本身使用Cloudflare做防护,对高频批量请求默认会做限流拦截,同时站点生成大seed对应的图片需要消耗大量服务器算力,请求频率过高时服务端本身也会处理失败返回500错误,这类问题无法完全避免,只能通过合理控制请求频率降低触发概率。

优化建议

  • 重写并发控制逻辑:每批最多创建3个任务,等待这批任务全部执行完成后再创建下一批,严格控制并发量不超过3
  • 替换所有 Thread.Sleep() 为 await Task.Delay()
  • 将RestClient改为全局单例
  • 给Random的所有访问加锁,或者使用 ThreadLocal<Random> 保证线程安全
  • 新增返回内容校验:判断响应头的 Content-Type 是否为 image/jpeg,或者校验返回字节流的前三位是否为jpg文件头 0xFF 0xD8 0xFF,确认是有效图片再写入本地
  • 新增请求重试机制:遇到500、502、超时错误时,间隔3-5秒后重试,单请求最多重试3次,可大幅提升成功率

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 19:54:05