C#多线程下载、断点续传的实现

简介: 做Unity热更功能的时候,发现单线程下载大尺寸资源文件的效率太低,专门去研究了下多线程下载,这里记录下相关知识点。

开源项目

首先,放上开源项目地址,基于Unity的下载模块,包含了多线程下载、断点续传的功能,可以直接使用。

https://github.com/GrayGuardian/DownloadFile

实现原理

  • 多线程下载

根据文件尺寸,将文件等分为X个数据段,再开启X个线程,每个线程设置下载起始位置,下载对应的数据段,最终按顺序将X个线程返回的下载数据拼接成一个byte[],后续可以将byte[]保存成文件

  • 断点续传

断点续传需要下载过程中时时写到本地文件,下载开始时,获取本地文件的尺寸X字节,然后设置以X字节为初始位置下载文件

这里可以发现,无论是多线程下载还是断点续传,都需要设置下载文件的起始位置,HTTP请求头的Range字段,可以实现下载部分资源的功能,C#有直接封装好操作Range的函数:

  • httpWebRequest.AddRange(long/int range)

    • 如果 range 为正,则 range 参数指定范围的起始点。 服务器应该开始从 range 指定的参数到 HTTP 实体中数据的末尾发送数据。
    • 如果 range 为负,则 range 参数指定范围的结束点。 服务器应该开始从 HTTP 实体中数据的起始到 range 指定的参数发送数据。
  • httpWebRequest.AddRange(long/int from, long/int to);

    • form:下载起始位置
    • to:下载结束位置

工作流

下面仅介绍多线程下载文件到本地的工作流,具备断点续传的功能

  1. 检查下载文件本地目录是否存在,若不存在,则创建
  2. 检查是否存在下载临时文件,若存在,则通过临时文件数量、尺寸等参数校验缓存数据是否有效,若无效则删除相关临时文件
  3. 检查临时文件的数量是否与线程数量一致,若不一致,则创建缺少的临时文件
  4. 请求URL的头部,获取到文件尺寸Size
  5. 将文件尺寸Size等分为X份的数据段form与to,将form加上临时文件的尺寸
  6. 开启X个线程,设置Range字段下载form到to之间的数据,每次读取到数据,直接写入对应的临时文件
  7. 下载完毕后,创建本地文件,读取临时文件的数据后直接删除,拼接后临时文件数据写入本地文件
相关文章
|
18天前
|
数据采集 JavaScript C#
C#图像爬虫实战:从Walmart网站下载图片
C#图像爬虫实战:从Walmart网站下载图片
|
2月前
|
数据采集 XML JavaScript
C# 中 ScrapySharp 的多线程下载策略
C# 中 ScrapySharp 的多线程下载策略
|
17天前
|
安全 数据库连接 API
C#一分钟浅谈:多线程编程入门
在现代软件开发中,多线程编程对于提升程序响应性和执行效率至关重要。本文从基础概念入手,详细探讨了C#中的多线程技术,包括线程创建、管理及常见问题的解决策略,如线程安全、死锁和资源泄露等,并通过具体示例帮助读者理解和应用这些技巧,适合初学者快速掌握C#多线程编程。
49 0
|
2月前
|
数据处理 Python
解锁Python多线程编程魔法,告别漫长等待!让数据下载如飞,感受科技带来的速度与激情!
【8月更文挑战第22天】Python以简洁的语法和强大的库支持在多个领域大放异彩。尽管存在全局解释器锁(GIL),Python仍提供多线程支持,尤其适用于I/O密集型任务。通过一个多线程下载数据的例子,展示了如何使用`threading`模块创建多线程程序,并与单线程版本进行了性能对比。实验表明,多线程能显著减少总等待时间,但在CPU密集型任务上GIL可能会限制其性能提升。此案例帮助理解Python多线程的优势及其适用场景。
28 0
|
2月前
|
安全 C# 开发者
【C# 多线程编程陷阱揭秘】:小心!那些让你的程序瞬间崩溃的多线程数据同步异常问题,看完这篇你就能轻松应对!
【8月更文挑战第18天】多线程编程对现代软件开发至关重要,特别是在追求高性能和响应性方面。然而,它也带来了数据同步异常等挑战。本文通过一个简单的计数器示例展示了当多个线程无序地访问共享资源时可能出现的问题,并介绍了如何使用 `lock` 语句来确保线程安全。此外,还提到了其他同步工具如 `Monitor` 和 `Semaphore`,帮助开发者实现更高效的数据同步策略,以达到既保证数据一致性又维持良好性能的目标。
32 0
|
2月前
|
存储 监控 Java
Java多线程优化:提高线程池性能的技巧与实践
Java多线程优化:提高线程池性能的技巧与实践
64 1
|
7天前
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
|
14天前
|
Java Spring
spring多线程实现+合理设置最大线程数和核心线程数
本文介绍了手动设置线程池时的最大线程数和核心线程数配置方法,建议根据CPU核数及程序类型(CPU密集型或IO密集型)来合理设定。对于IO密集型,核心线程数设为CPU核数的两倍;CPU密集型则设为CPU核数加一。此外,还讨论了`maxPoolSize`、`keepAliveTime`、`allowCoreThreadTimeout`和`queueCapacity`等参数的设置策略,以确保线程池高效稳定运行。
78 10
spring多线程实现+合理设置最大线程数和核心线程数
|
23天前
|
Java 数据库 Android开发
一个Android App最少有几个线程?实现多线程的方式有哪些?
本文介绍了Android多线程编程的重要性及其实现方法,涵盖了基本概念、常见线程类型(如主线程、工作线程)以及多种多线程实现方式(如`Thread`、`HandlerThread`、`Executors`、Kotlin协程等)。通过合理的多线程管理,可大幅提升应用性能和用户体验。
41 15
一个Android App最少有几个线程?实现多线程的方式有哪些?