继上篇的基础准备 从资源服务器下载资源(一)

我们现在继续进一步完成 LoadManager 管理类。

管理类因为在全局中都是存在的,所以应该作为单例存在。

因为LoadManager 类是管理多个 LoadRequest的,所以我们需要存储当前正在下载的LoadRequest,以及下载完成的 LoadRequest。

另外,我们为了防止太多下载线程占用过多资源,我们对于下载的线程个数做一定的限制,如项目里面的最大线程数为2,所以我们需要一个存储LoadRequest的等待队列。

根据以上分析,分别如下:

[csharp] view plaincopy

  1. public static LoadManager instance;

  2. public int MAX_LOAD_REQUEST = 2;

  3. private Dictionary<string, LoadRequest> loadDict = new Dictionary<string, LoadRequest>();

  4. private Dictionary<string, LoadRequest> waitDict = new Dictionary<string, LoadRequest>();

  5. private Dictionary<string, LoadParam> completeDict = new Dictionary<string, LoadParam>();

另外,既然有下载队列的存在,就有下载优先级,我们可以多一个存储下载任务的优先级,然后根据优先级进行下载。

当然,项目里面虽然有了下载优先级的存储,但是并没有进行排序,在进行下载任务创建的时候,也都统一使用了Normal优先级。

所以在此我们先跟着创建,等到以后需要使用优先级的时候再进行排序。

[csharp] view plaincopy

  1. private List<string> priorityList = new List<string>();

接下来我们开始实现代码:

1. 首先实现单例:

[csharp] view plaincopy

  1. /// <summary>

  2. ///  返回实例

  3. /// </summary>

  4. /// <returns></returns>

  5. public static LoadManager getInstance() {

  6. if (instance == null) {

  7. instance = new LoadManager();

  8. }

  9. return instance;

  10. }

2. 我们实现一个函数,功能是根据优先级,从等待队列里面移除一个任务到下载队列里。

[csharp] view plaincopy

  1. /// <summary>

  2. /// 根据优先级,从等待队列里面移除一个任务到下载队列里

  3. /// </summary>

  4. public void MoveRequestFromWaitDictToLoadDict() {

  5. isLoading = loadDict.Count > 0;

  6. if (priorityList.Count > 0) {

  7. if (waitDict.ContainsKey(priorityList[0])) {

  8. LoadRequest request = waitDict[priorityList[0]];

  9. waitDict.Remove(priorityList[0]);

  10. priorityList.RemoveAt(0);

  11. Load(request.requestURL, request.completeFunction, request.customParams, request.fileType, request.priotiry, request.errorFunction, request.processFunction);

  12. }

  13. }

  14. }

3.上面的Load()函数是加载新的LoadRequest。

在加载新的LoadRequest时,我们要进行判断,例如同个下载任务可能是由不同的组件请求发起的;

① 这个时候我们当然不能再去下载一次,所以只需判断completeDict里面是否已经下载过了,如果是,就直接使用即可。

② 另外,当有相同的请求时,不过此时下载还没完成(正在下载中),此时我们只需把回调函数加进回调队列即可。

③ 相同的,如果相同的请求在等待队列,也跟②一样处理。

④ 最后就剩下是,从没下载过的情况,此时我们要看当前下载的线程是否超过最大限制,如果是,则把任务加到等待队列,如果不是,则可马上下载

具体实现为下:

[csharp] view plaincopy

  1. /// <summary>

  2. /// 读取资源

  3. /// </summary>

  4. public void Load(string url, LoadRequest.DownCompleteDelegate completeFunc, object customParam = null, string fileType = "", int  priority = 2, LoadRequest.ErrorDelegate errorFunc = null, LoadRequest.ProcessDelegate processFunc = null) {

  5. url = url.Trim();

  6. if (string.IsNullOrEmpty(url)) return;

  7. if (completeDict.ContainsKey(url)) {

  8. // 已下载资源,直接调用回调函数

  9. if (customParam != null) {

  10. completeDict[url].param = customParam;

  11. }

  12. try {

  13. completeFunc.Invoke(completeDict[url]);

  14. } catch (Exception exception) {

  15. Debug.LogWarning("exception:" + exception.Message);

  16. }

  17. } else if (loadDict.ContainsKey(url)) {

  18. // 已经提交相同请求,但是没有下载完成

  19. loadDict[url].completeFunction += completeFunc;

  20. loadDict[url].processFunction += processFunc;

  21. loadDict[url].errorFunction += errorFunc;

  22. loadDict[url].customParams.Add(customParam);

  23. } else if (waitDict.ContainsKey(url)) {

  24. // 已经提交相同请求,但是还没轮到加载

  25. loadDict[url].completeFunction += completeFunc;

  26. loadDict[url].processFunction += processFunc;

  27. loadDict[url].errorFunction += errorFunc;

  28. loadDict[url].customParams.Add(customParam);

  29. } else {

  30. // 未加载过的

  31. if (loadDict.Count < MAX_LOAD_REQUEST) {

  32. isLoading = true;

  33. LoadRequest loadRequest = new LoadRequest(url, customParam, fileType, completeFunc, errorFunc, processFunc);

  34. if (customParam != null && customParam.GetType().ToString() == "System.Collections.Generic.List`1[System.Object]") {

  35. loadRequest.customParams = (List<object>)customParam;

  36. }

  37. loadDict.Add(url, loadRequest);

  38. } else {

  39. // 已达到最大加载数目,加入等待队列

  40. LoadRequest loadRequest = new LoadRequest();

  41. loadRequest.requestURL = url;

  42. loadRequest.completeFunction = completeFunc;

  43. loadRequest.errorFunction = errorFunc;

  44. loadRequest.processFunction = processFunc;

  45. loadRequest.customParams.Add(customParam);

  46. loadRequest.fileType = fileType;

  47. loadRequest.priotiry = priority;

  48. waitDict.Add(url, loadRequest);

  49. priorityList.Add(url);

  50. priorityList = priorityList.OrderBy(s => waitDict[s].priotiry).ToList();

  51. }

  52. }

  53. }

转载于:https://blog.51cto.com/568464209/1759280

【Unity3d】【项目学习心得】从资源服务器下载资源(二)相关推荐

  1. 【QT从零开始系列12】QT学习心得及资源汇总

    文章目录 下载方面 Qt官网下载(非常慢) Qt 国内镜像站下载(较快) 书籍 C++ GUI Qt 4编程(第二版).pdf Qt5 开发实战 Qt5 开发及实例 Qt Creator快速入门 视频 ...

  2. android项目学习心得(全源导航)

    1.acitivity的跳转,返回上一个界面是结束当前界面,而不是从当前界面去跳转前一个界面(即将前一个界面创建了一遍),概念要理清,具体写法由隐式和显式多种写法.像这种操作UI界面,可以多使用fra ...

  3. C#项目学习 心得笔记本

    CacheDependency 缓存 //创建缓存依赖项CacheDependency dep = new CacheDependency(fileName);//创建缓存HttpContext.Cu ...

  4. 慕课网基于ElasticSearch的找房网实战开发企业级房屋搜索网项目学习心得(一)

    个人资源与分享网站:http://xiaocaoshare.com/ 1.技术架构 SpringBoot+Spring Data Jpa+mysql+ES+Redis+Thymeleaf+bootst ...

  5. 一个用python做的完整项目_我从一个小项目学习Python编程的全过程(二)

    在(一)中的时候我们分析了如何获取所有人无忧币的统计情况,接下来开始学着写代码了: 首先第一步我们得把第一个页面的源代码:#coding:utf-8 import urllib url = 'http ...

  6. Oracle的学习心得和知识总结(二十五)|Oracle数据库Real Application Testing之真实应用测试概述白皮书

    目录结构 注:提前言明 本文借鉴了以下博主.书籍或网站的内容,其列表如下: 1.参考书籍:<Oracle Database SQL Language Reference> 2.参考书籍:& ...

  7. 微人事项目学习之登陆页面制作(二)

    学习SpringBoot+Vue前后端分离项目,原项目GitHub地址,项目作者江雨一点雨博客. 制作登录页面 接上篇文章,正式开始制作登陆页面,本文中包括以后的文章中所有的关于element-ui的 ...

  8. python revit二次开发_BIM学习心得3-简单讲讲Revit二次开发学习方法

    好久没更新了,差点以为自己要断更了,临近要毕业,一直在忙着找工作,没有对口的,苦啊- 不倒苦水了,上一次说到BIM学习的四个步骤之一,建模,这个主要在于熟练度,如果软件熟练了,基本上什么都能画了,公路 ...

  9. HTML的学习心得和知识总结(二)|HTML基础和高级标签汇总

    目录结构 HTML基础和高级标签汇总 文章快速说明索引 HTML 的基础标签 HTML 的高级标签 文章快速说明索引 学习目标: 可视化和部分交互功能的前端开发内容的学习:HTML CSS JavaS ...

最新文章

  1. Java中常量定义的几种方式
  2. 10多所高校发布通知: 今年研究生复试或有变!
  3. Java 多线程(一) 基础知识与概念
  4. 基于linux-2.6.32.2的servfox移植
  5. 三宝机器人怎么充电_巨人通力导致吉祥三宝+36号故障怪现象的又一因素
  6. MS SQL Server 2008 简体中文正式版下载地址(附序列号)
  7. 【每日算法Day 99】你们可能不知道只用20万赢到578万是什么概念
  8. 音乐网站源码:Spring Boot + MyBatis + Vue 实现的
  9. stm32呼吸灯程序_STM32寄存器操作点亮LED灯
  10. Android 键盘映射
  11. c15语言中不支持十六进制的数据,从十六进制字符串中提取数据
  12. 关系数据库(范式判断、函数依赖、无损分解、正则覆盖)
  13. 洛谷 U5773 受望先锋
  14. 上位机开发之三菱Q系列PLC通信实践
  15. 路由器的两个端口接在同一个交换机上_什么是路由器交换机?路由器交换机介绍!...
  16. mac安装配置maven
  17. Android 方向传感器的简单使用
  18. 100天精通Andriod逆向——第3天:真机环境配置
  19. 做完近视手术应该注意什么?近视术后护理攻略请你收下
  20. golang 打桩,mock 数据怎么玩?

热门文章

  1. 网络管理与维护作业11
  2. Android全局异常捕获
  3. 墨菲定律与 IndexOutOfBoundsException(数组越界异常)
  4. CentOS 7下mysqld服务启动失败终极解决方案
  5. 在Java中的foreach循环中调用remove
  6. 我可以编写一个CSS选择器来选择不具有某个类或属性的元素吗?
  7. win11很卡怎么办 windows11很卡的解决方法
  8. win11系统通知怎么取消 Windows11取消系统通知的步骤方法
  9. tab vue 竖排_vue tab切换的几种方式
  10. linux驱动程序文件,急,linux驱动程序是对的为什么生成不了.o驱动程序文件