silverlight游戏设计(二)资源管理篇(上)--实现一个多任务资源下载器
2010-12-21 22:32
543 查看
我在silverlight游戏设计(一)主程序加载器这篇文章中写的那个加载器中其实已经包含了一个下载器。不过本篇需要的是一个在游戏运行时动态执行的下载器,这两者有什么区别呢?一方面在于前篇的那个下载器是串行下载所有文件,而对于一个正在运行的网游,因为我们对大部分资源(比如图片、脚本等)采取动态加载的策略,所以它随时都有可能去请求下载,也就是需要同时进行更多的下载任务;二是我们这个下载器与接下来资源管理服务时紧密相关,所以需要重新设计新的接口。
设计要点
DownloadDelegaternamespace Sopaco.Silverlight.Insfrastructure.Net.DownloadActivator
{
public class DownloadDelegater : IDisposable
{
class InnerBuffData
{
public Uri Uri
{
get;
set;
}
public DownloadResultEventHandler Handler
{
get;
set;
}
}
#region Constaints
private readonly static int DEFAULT_CONNECTION_IN_POOL = 5;
#endregion
#region Fields
/// <summary>
/// 池化WebClient
/// </summary>
private IGenericPool<WebClient> _webClients = new GenericPool<WebClient>();
/// <summary>
/// 缓冲,当WebClient数量达到限制时将需要等待的资源Uri放到这里。
/// </summary>
private Queue<InnerBuffData> _buffTargets = new Queue<InnerBuffData>();
/// <summary>
/// 最大启用的WebClient数量
/// </summary>
private int _maxConnectionInPool = DEFAULT_CONNECTION_IN_POOL;
/// <summary>
/// 当前进行中的WebClient数量
/// </summary>
private int _currentWorkersNum = 0;
#endregion
#region lockers
private object _lock_CurrentWorkersNum = new object();
private object _lock_BuffTargets = new object();
#endregion
#region ctors
public DownloadDelegater()
{
}
#endregion
#region Properties
public int MaxConnectionInPool
{
get
{
return _maxConnectionInPool;
}
set
{
_maxConnectionInPool = value;
}
}
#endregion
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();
}
#region IDisposable Members
public void Dispose()
{
disposeWebclientPool();
_webClients.Dispose();
}
#endregion
#region Private Helper Methods
private void disposeWebclientPool()
{
_webClients.Compact(0);
}
private void onDownloadResultArrive(object sender, OpenReadCompletedEventArgs args)
{
var callback = args.UserState as DownloadResultEventHandler;
var client = sender as WebClient;
if(args.Result != null && args.Error == null && !args.Cancelled)
{
var memStream = new MemoryStream();
args.Result.CopyTo(memStream);
memStream.ResetPosition();
callback(memStream, DownloadStatus.Completed);
}
else
{
if(args.Cancelled)
{
callback(null, DownloadStatus.Canceled);
}
else
{
callback(null, DownloadStatus.Error);
}
}
lock (_lock_BuffTargets)
{
if (_buffTargets.Count != 0)
{
var targetInfo = dequeue();
client.OpenReadAsync(targetInfo.Uri, targetInfo.Handler);
}
else
{
client.OpenReadCompleted -= onDownloadResultArrive;
decreaseRefCounter();
_webClients.Attach(client);
return;
}
}
}
private void increaseRefCounter()
{
lock (_lock_CurrentWorkersNum)
{
_currentWorkersNum++;
}
}
private void decreaseRefCounter()
{
lock (_lock_CurrentWorkersNum)
{
_currentWorkersNum--;
}
}
private void enqueue(InnerBuffData data)
{
lock(_lock_BuffTargets)
{
_buffTargets.Enqueue(data);
}
}
private InnerBuffData dequeue()
{
lock(_lock_BuffTargets)
{
return _buffTargets.Dequeue();
}
}
#endregion
}
}完整源码下载
[/code]
设计要点
DownloadDelegaternamespace Sopaco.Silverlight.Insfrastructure.Net.DownloadActivator
{
public class DownloadDelegater : IDisposable
{
class InnerBuffData
{
public Uri Uri
{
get;
set;
}
public DownloadResultEventHandler Handler
{
get;
set;
}
}
#region Constaints
private readonly static int DEFAULT_CONNECTION_IN_POOL = 5;
#endregion
#region Fields
/// <summary>
/// 池化WebClient
/// </summary>
private IGenericPool<WebClient> _webClients = new GenericPool<WebClient>();
/// <summary>
/// 缓冲,当WebClient数量达到限制时将需要等待的资源Uri放到这里。
/// </summary>
private Queue<InnerBuffData> _buffTargets = new Queue<InnerBuffData>();
/// <summary>
/// 最大启用的WebClient数量
/// </summary>
private int _maxConnectionInPool = DEFAULT_CONNECTION_IN_POOL;
/// <summary>
/// 当前进行中的WebClient数量
/// </summary>
private int _currentWorkersNum = 0;
#endregion
#region lockers
private object _lock_CurrentWorkersNum = new object();
private object _lock_BuffTargets = new object();
#endregion
#region ctors
public DownloadDelegater()
{
}
#endregion
#region Properties
public int MaxConnectionInPool
{
get
{
return _maxConnectionInPool;
}
set
{
_maxConnectionInPool = value;
}
}
#endregion
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();
}
#region IDisposable Members
public void Dispose()
{
disposeWebclientPool();
_webClients.Dispose();
}
#endregion
#region Private Helper Methods
private void disposeWebclientPool()
{
_webClients.Compact(0);
}
private void onDownloadResultArrive(object sender, OpenReadCompletedEventArgs args)
{
var callback = args.UserState as DownloadResultEventHandler;
var client = sender as WebClient;
if(args.Result != null && args.Error == null && !args.Cancelled)
{
var memStream = new MemoryStream();
args.Result.CopyTo(memStream);
memStream.ResetPosition();
callback(memStream, DownloadStatus.Completed);
}
else
{
if(args.Cancelled)
{
callback(null, DownloadStatus.Canceled);
}
else
{
callback(null, DownloadStatus.Error);
}
}
lock (_lock_BuffTargets)
{
if (_buffTargets.Count != 0)
{
var targetInfo = dequeue();
client.OpenReadAsync(targetInfo.Uri, targetInfo.Handler);
}
else
{
client.OpenReadCompleted -= onDownloadResultArrive;
decreaseRefCounter();
_webClients.Attach(client);
return;
}
}
}
private void increaseRefCounter()
{
lock (_lock_CurrentWorkersNum)
{
_currentWorkersNum++;
}
}
private void decreaseRefCounter()
{
lock (_lock_CurrentWorkersNum)
{
_currentWorkersNum--;
}
}
private void enqueue(InnerBuffData data)
{
lock(_lock_BuffTargets)
{
_buffTargets.Enqueue(data);
}
}
private InnerBuffData dequeue()
{
lock(_lock_BuffTargets)
{
return _buffTargets.Dequeue();
}
}
#endregion
}
}完整源码下载
[/code]
相关文章推荐
- silverlight游戏设计(二)资源管理篇(下)--资源的状态通知、管理与缓存
- silverlight游戏设计(二)资源管理篇(补充)--图片帧序列资源包解析与图片资源处理
- Silverlight游戏设计(Game Design):(十四)练习用游戏素材资源的获取及相关工具使用心得
- Silverlight游戏设计(Game Design):(十四)练习用游戏素材资源的获取及相关工具使用心得
- 游戏任务成就体系的实现(附三):成就系统基于Mysql+Cache的数据库访问设计实现
- Silverlight游戏设计(Game Design):(十四)练习用游戏素材资源的获取及相关工具使用心得
- Silverlight游戏设计(Game Design):(十四)练习用游戏素材资源的获取及相关工具使用心得
- 游戏任务成就体系的实现(附七):成就系统基于Redis的数据库访问设计实现
- Silverlight游戏设计(Game Design):(十四)练习用游戏素材资源的获取及相关工具使用心得 --转
- Silverlight游戏设计(Game Design):(十四)练习用游戏素材资源的获取及相关工具使用心得
- 们只是「电脑玩物」 首页 实用技巧 免费资源 超好玩的游戏 软件推荐 IT技术 资讯 编程 其它 MVVM设计模式和WPF中的实现(四) 事件绑定 07net01.com 发布于 2015-10-08
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(八) 完美实现A*寻径动态动画
- 外国网站codeproject中的比较好的silverlight资源整理3-类似连连看-气泡Breaker游戏
- Silverlight游戏设计(Game Design):(一)游戏中斜视角的原理与分析
- (转)在Unity3D的网络游戏中实现资源动态加载
- Silverlight游戏设计(Game Design):(十三)帝国时代II (Demo) 之 “战争艺术”②
- vue+webpack实现精美游戏设计:实现建筑物的渐变生成效果
- [Python网络编程]浅析守护进程后台任务的设计与实现
- Unity3D实现动态加载游戏资源
- J2ME射击游戏实现示例(含源代码和资源)