Unity开发(一) 多线程断点续传文件下载管理器(上)

本文介绍了在Unity游戏中为解决热更新需求,如何设计一个高效的多线程断点续传文件下载管理器。讨论了下载中可能出现的问题,如网络波动、文件错误等,并提出解决方案。文章详细讲解了下载管理器的结构,包括数据结构、框架代码、多线程逻辑、回调管理以及网络相关部分,旨在实现稳定、可恢复的文件下载。
摘要由CSDN通过智能技术生成

游戏的热更需求

在游戏开发中,热更并下载资源,对商业化游戏来说是一个必须的需求。而想要高效并稳定地下载文件一直是开发中的一个痛点。我们能看到市面上,大量游戏都在下载上卡死,断网,重启无效等等问题。我们来总结一下要解决的问题:

  1. 网络请求异常处理——断网、请求失败、请求超时、网络波动、下载到一半等问题
  2. 文件读写异常处理——文件读失败、文件写失败、文件写一半等问题
  3. 游戏进程异常处理——下载到一半、文件写一半、玩家退出等问题
  4. 重启现场恢复处理——可恢复性,继续下载
  5. 文件的下载正确性——文件长度、文件校验,文件可读性
  6. 文件线程高效下载——多线程,异步回调文件

上述还只是针对下载会出现的问题,对于版本管理导致的问题,下一篇文章再讨论。
下文会为上述的每个问题,提供对应的解决方案。

下载管理器

下图是下载管理器的结构,外部只暴露三个函数,负责异步下载同步下载下载回调刷新

外部接口
请求
请求
刷新
每帧调用
DownloadAsync
DownloadSync
DownloadUpdate
下载管理器
DownloadMac子线程A
DownloadMac子线程B
DownloadMac子线程C
主线程

内部对同步下载,直接返回结果。
内部实现对异步下载创建线程,对外部隐藏异步线程。
上述异步回调实际上是通过主线程调用DownloadUpdate来遍历的同步回调

TIP:为什么设计成Update里同步回调呢?

如果直接通过异步线程进行回调,那么在回调函数里必须要处理线程锁的问题和回调可能运行逻辑报错的问题,这样势必造成代码的耦合度增加。
而通过主线程调用Update来回调,可以隐藏了线程逻辑,也可以保证主线程的线性运行。

下载请求数据结构

public delegate void DonwloadErrorCallBack(DownloadUnit downUnit, string msg);
public delegate void DonwloadProgressCallBack(DownloadUnit downUnit, int curSize, int allSize);
public delegate void DonwloadCompleteCallBack(DownloadUnit downUnit);

public class DownloadUnit
{
   
    public string name; //下载的文件,作为标识
    public string downUrl; //远程地址
    public string savePath; //本地地址
    public int size; //文件长度,非必须
    public string md5; //需要校验的md5,非必须
    public bool isDelete; //用于清理正在下载的文件

    public DonwloadErrorCallBack errorFun;
    public DonwloadProgressCallBack progressFun;
    public DonwloadCompleteCallBack completeFun;
}

数据结构主要提供了下载必要的参数和常用的三个回调函数。

下载管理器框架代码

由上述,可以写出如下的一个代码框架

public class DownloadMgr
{
   
    private static DownloadMgr _Instance = null;

    public static DownloadMgr I
    {
   
        get
        {
   
            if (_Instance == null) _Instance = new DownloadMgr();
            return _Instance;
        }
    }
    private DownloadMgr()
    {
   
    }
    //异步会创建线程
    public void DownloadAsync(DownloadUnit info)
    {
   
    }
    //同步不会调用回调函数,返回是否成功
    public bool DownloadSync(DownloadUnit info)
    {
   
    }
    //请将Updata放到主线程Update中
    public void Update()
    {
   
    }
}

多线程运行逻辑

很多人可能会有一个简单处理方法,一个文件一个线程,运行结束就销毁。
too young too simple C#中一个线程要占用1M的内存,而在热更中,几千个小文件轻轻松松的。
那么,我们需要解决几个问题:

  1. 线程的数量上限——内存占用上限,同时运行数量
  2. 线程的重复利用——降低创建销毁开销
  3. 线程内存释放——下载结束,不占用内存

很简单的,我们就能想到生产者-消费者模型

外部代码调用
循环取出下载
取出
取出
Unity中的多线程断点续传是一种技术,用于在文件传输过程中出现中断时能够自动恢复传输并继续未完成的部分。它的目的是提高文件传输的效率和稳定性。 在Unity中实现多线程断点续传的一种常见方式是使用协程和分块传输。首先,需要将大文件分成若干个固定大小的块,每个块独立传输。然后,使用协程开启多个线程,同时传输这些块。如果传输过程中出现中断,只需要记录已经传输完成的块和传输进度,下次继续传输时可以先检查已完成的块,并从断点处继续传输未完成的块。这样可以避免从头开始传输整个文件。 多线程断点续传的好处是可以更加高效地传输大文件。通过同时传输多个块,可以将文件传输时间大大缩短。而断点续传的功能则保证了即使传输中断,也能够从中断处继续传输,避免重新传输整个文件,减少了时间和资源的浪费。 然而,实现多线程断点续传也存在一些挑战。首先,需要确保多个线程之间的同步和互斥,以避免数据冲突和竞争条件。其次,需要处理可能出现的网络异常和传输错误,以保证传输的稳定性和可靠性。此外,为了方便管理和监控传输过程,也需要实现相关的进度条和错误处理机制。 总而言之,Unity中的多线程断点续传是一种优化文件传输的技术,通过分块传输和使用协程来实现在传输中断时能够自动恢复并继续传输。它可以提高传输效率和稳定性,适用于需要传输大文件的应用场景。
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值