惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
T
Threatpost
Latest news
Latest news
N
News | PayPal Newsroom
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Help Net Security
Help Net Security
D
Darknet – Hacking Tools, Hacker News & Cyber Security
AI
AI
Simon Willison's Weblog
Simon Willison's Weblog
TaoSecurity Blog
TaoSecurity Blog
The Last Watchdog
The Last Watchdog
L
LINUX DO - 热门话题
Google DeepMind News
Google DeepMind News
T
Threat Research - Cisco Blogs
O
OpenAI News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
The Exploit Database - CXSecurity.com
NISL@THU
NISL@THU
Application and Cybersecurity Blog
Application and Cybersecurity Blog
S
Securelist
小众软件
小众软件
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Martin Fowler
Martin Fowler
S
SegmentFault 最新的问题
Cisco Talos Blog
Cisco Talos Blog
云风的 BLOG
云风的 BLOG
AWS News Blog
AWS News Blog
GbyAI
GbyAI
N
News and Events Feed by Topic
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
美团技术团队
Engineering at Meta
Engineering at Meta
A
About on SuperTechFans
博客园 - 三生石上(FineUI控件)
S
Schneier on Security
博客园 - 聂微东
V2EX - 技术
V2EX - 技术
T
Troy Hunt's Blog
SecWiki News
SecWiki News
S
Secure Thoughts
B
Blog RSS Feed
Hugging Face - Blog
Hugging Face - Blog
WordPress大学
WordPress大学
腾讯CDC
H
Heimdal Security Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Apple Machine Learning Research
Apple Machine Learning Research
月光博客
月光博客
www.infosecurity-magazine.com
www.infosecurity-magazine.com
P
Privacy International News Feed

博客园 - kiminozo

UAP如何根据DeviceFamily显示不同的页面 Windows 10 响应式设计和设备友好的开发 Windows Phone Toolkit for WP8 已经出了 代码分享 ScrollViewerListener 获取ScrollViewer的位置改变 经验 C#手动同步的滥用实例 WP7技巧 扩展【共享...】按钮 Bangumi 番組計劃 WP手机客户端发布 WP7进阶技巧 自定义Toast 提示动画效果 WP7自定义控件 TabSwitch控件 模拟Windows phone 开始菜单的瓦片动画 WP7自定义控件 评分控件 WP7应用开发笔记 TiltEffect为控件添加倾斜的触控响应效果 从FLC中学习的设计模式系列-结构型模式(3)-享元模式 WP7应用开发笔记 继承BitmapSource并使用独立存储来缓存远程的图片 解决log4net在.net 4.0 ClientProfile下无法使用 从FLC中学习的设计模式系列-结构型模式(2)-装饰 从FLC中学习的设计模式系列-结构型模式(1)-适配器 从FLC中学习的设计模式系列-创建型模式(5)-原型 从FLC中学习的设计模式系列-创建型模式(4)-建造者
用代理类包装异步调用方法实现异步命令
kiminozo · 2012-02-27 · via 博客园 - kiminozo

C#开发中经常需要使用使用异步操作,特别是Windows phone和Silverlight下层的很多IO相关的访问都是异步的。
标准异步方法一般都是Begin[Invoke]和End[Invoke]的一对方法,用法就不多说了。

我最近在写用命令模式常用的HttpRequest操作,就想将命令包装成异步方法,
想了很久使用了下面的方式包装异步:

首先是常规的异步调用时序:

现在使用包装使用了2个类一个用于包装AsyncCallback,一个用于包装IAsyncResult,来包装这个时序。
类的代码如下:

 /// <summary>
/// 异步回调代理
/// </summary>
public class AsyncCallbackDelegate
{
/// <summary>
/// 需要代理的异步回调
/// </summary>
private readonly AsyncCallback asyncCallback;

/// <summary>
/// 原始调用对象
/// </summary>
public object Delegate { get; set; }

public AsyncResultDelegate Result { get; set; }

/// <summary>
/// 构造 异步回调代理
/// </summary>
/// <param name="asyncCallback">需要代理的异步回调</param>
public AsyncCallbackDelegate(AsyncCallback asyncCallback)
{
this.asyncCallback = asyncCallback;
}

/// <summary>
/// 包装后的异步回调
/// </summary>
/// <param name="asyncResult"></param>
public void AsyncCallBack(IAsyncResult asyncResult)
{
//用AsyncResultDelegate包装asyncResult
var asyncResultDelegate = new AsyncResultDelegate(asyncResult) { Delegate = Delegate };
asyncCallback(asyncResultDelegate);//调用原始异步回调
}
}

/// <summary>
/// 异步状态代理
/// </summary>
public class AsyncResultDelegate : IAsyncResult
{
/// <summary>
/// 原始异步状态
/// </summary>
private readonly IAsyncResult asyncResult;

/// <summary>
/// 原始调用对象
/// </summary>
public object Delegate { get; set; }

public AsyncResultDelegate(IAsyncResult asyncResult)
{
this.asyncResult = asyncResult;
}

#region 装饰模式包装

public object AsyncState
{
get { return AsyncResult.AsyncState; }
}

public System.Threading.WaitHandle AsyncWaitHandle
{
get { return AsyncResult.AsyncWaitHandle; }
}

public bool CompletedSynchronously
{
get { return AsyncResult.CompletedSynchronously; }
}

public bool IsCompleted
{
get { return AsyncResult.IsCompleted; }
}

public IAsyncResult AsyncResult
{
get { return asyncResult; }
}
#endregion
}

包装后的调用时序:


演示代码AddCommand 用于使用代理包装异步执行a+b返回结果

public class AddCommand
{
private readonly int a;
private readonly int b;

public AddCommand(int a, int b)
{
this.a = a;
this.b = b;
}

public IAsyncResult BeginInvoke(AsyncCallback asyncCallback, object state)
{
Func<int, int, int> addFunc = (x, y) => x + y;//测试用的原始异步调用对象

AsyncCallback callbackDelegate = asyncCallback;
if (asyncCallback != null)
{
//用AsyncCallbackDelegate包装AsyncCallback
var tmp = new AsyncCallbackDelegate(asyncCallback) { Delegate = addFunc };
callbackDelegate = tmp.AsyncCallBack;
}
var asyncResult = addFunc.BeginInvoke(a, b, callbackDelegate, state);
//用AsyncResultDelegate包装asyncResult
return new AsyncResultDelegate(asyncResult) { Delegate = addFunc };
}

public int EndInovke(IAsyncResult result)
{
var asyncResultDelegate = (AsyncResultDelegate)result;//还原AsyncResultDelegate
Func<int, int, int> addFunc = (Func<int, int, int>)asyncResultDelegate.Delegate;//获得原始对象
return addFunc.EndInvoke(asyncResultDelegate.AsyncResult);//传入原始AsyncResult
}
}

调用AddCommand 支持2种调用方式

class Program
{
static void Main(string[] args)
{
//主线程等待后调用EndInovke
{
AddCommand invoker = new AddCommand(1, 2);
var async = invoker.BeginInvoke(null, null);
async.AsyncWaitHandle.WaitOne();
int result = invoker.EndInovke(async);
Console.WriteLine(result);
}

//由CallBack调用EndInovke
{
AddCommand invoker = new AddCommand(5, 9);
var async = invoker.BeginInvoke(CallBack, invoker);
async.AsyncWaitHandle.WaitOne();
}
Console.ReadLine();
}

static void CallBack(IAsyncResult asyncResult)
{
AddCommand invoker = asyncResult.AsyncState as AddCommand;
int result = invoker.EndInovke(asyncResult);
Console.WriteLine(result);
}

}

varcolor: #0000ff;

/spanspan style=