我在silverlight游戏设计(一)主程序加载器这篇文章中写的那个加载器中其实已经包含了一个下载器。不过本篇需要的是一个在游戏运行时动态执行的下载器,这两者有什么区别呢?一方面在于前篇的那个下载器是串行下载所有文件,而对于一个正在运行的网游,因为我们对大部分资源(比如图片、脚本等)采取动态加载的策略,所以它随时都有可能去请求下载,也就是需要同时进行更多的下载任务;二是我们这个下载器与接下来资源管理服务时紧密相关,所以需要重新设计新的接口。
设计要点
a.限制webclient数量,池化webclient
带宽总是有限的,我们不可能每次需要下载一个资源时都new一个webclient,最好的方式是我们可以通过配置限定最多允许多少个webclient执行下载任务,多出这个数量的下载请求先辈暂存起来,当其他下载任务结束时再进行下载。
关于这个功能的实现,我们可以先判断当前工作中的webclient数量,如果大于限制数则将任务请求存放到队列中。
public void Download(Uri uri, DownloadResultEventHandler callback)
{
if(_currentWorkersNum + 1 > _maxConnectionInPool)
{
enqueue(new InnerBuffData() { Uri = uri, Handler = callback });
return;
}
var client = _webClients.Detach();
client.OpenReadCompleted += onDownloadResultArrive;
client.OpenReadAsync(uri, callback);
increaseRefCounter();
}
{
if(_currentWorkersNum + 1 > _maxConnectionInPool)
{
enqueue(new InnerBuffData() { Uri = uri, Handler = callback });
return;
}
var client = _webClients.Detach();
client.OpenReadCompleted += onDownloadResultArrive;
client.OpenReadAsync(uri, callback);
increaseRefCounter();
}