利用TaskCompletionSource将EAP转换成TAP
2024-08-20 23:05:06
1.原始的异步方法的调用
我们来看个简单的例子,在这里演示调用 WebClient.DownloadStringAsync 方法(这个方法不是 TAP),然后由 WebClient.DownloadStringCompleted 事件通知 UI 更新,这是大多数人都会用的方法。
- private
void DownloadString(string address) - {
- WebClient wc = new WebClient();
- wc.DownloadStringCompleted += (sender, e) =>
- {
- if (e.Cancelled)
- this.textBox1.Text = "Cancel";
- else
if (e.Error != null) - this.textBox1.Text = "Error";
- else
- this.textBox1.Text = e.Result;
- };
- wc.DownloadStringAsync(new Uri(address));
- }
客户端调用
- private
void button_DownloadString_Click(object sender, EventArgs e) - {
- DownloadString("https://www.google.com.tw/");
- }
这是一个很简单的例子,一旦若项目里有成千上万的通知事件跟 UI 绑在一起,维护起来会相当的痛苦。
2.将 EAP 转换成 TAP步骤
- 命名规则以 Async 为后缀
- 返回 Task 或是 Task<TResult>
- 调用 TaskCompletionSource 方法
改变 Task 状态可调用以下三个方法:SetCanceled、SetException、SetResult
- private Task<string> DownloadStringAsync(string address)
- {
- var tcs = new TaskCompletionSource<string>();
- WebClient wc = new WebClient();
- wc.DownloadStringCompleted += (sender, e) =>
- {
- if (e.Cancelled)
- tcs.SetCanceled();
- else
if (e.Error != null) - tcs.SetException(e.Error);
- else
- tcs.SetResult(e.Result);
- };
- wc.DownloadStringAsync(new Uri(address));
- return tcs.Task;
- }
客户端调用
- private async void button_DownloadStringAsync_Click(object sender, EventArgs e)
- {
- var task = DownloadStringAsync("https://www.google.com.tw/");
- await task;
- if (task.IsCanceled)
- {
- this.textBox1.Text = "Cancel";
- }
- else
if (task.IsFaulted) - {
- this.textBox1.Text = "Error";
- }
- else
if (task.IsCompleted) - {
- this.textBox1.Text = task.Result;
- }
- }
转自:http://www.it165.net/pro/html/201308/6710.html
3.微软的封装
- public
static
Task<byte[]> DownloadDataTask(this WebClient webClient, Uri address) - {
- // Create the task to be returned
- var tcs = new TaskCompletionSource<byte[]>(address);
- // Setup the callback event handler
- DownloadDataCompletedEventHandler handler = null;
- handler = (sender, e) => EAPCommon.HandleCompletion(tcs, e, () => e.Result, () => webClient.DownloadDataCompleted -= handler);
- webClient.DownloadDataCompleted += handler;
- // Start the async work
- try
- {
- webClient.DownloadDataAsync(address, tcs);
- }
- catch(Exception exc)
- {
- // If something goes wrong kicking off the async work,
- // unregister the callback and cancel the created task
- webClient.DownloadDataCompleted -= handler;
- tcs.TrySetException(exc);
- }
- // Return the task that represents the async operation
- return tcs.Task;
- }
- internal
class EAPCommon - {
- internal
static
void HandleCompletion<T>( - TaskCompletionSource<T> tcs, AsyncCompletedEventArgs e, Func<T> getResult, Action unregisterHandler)
- {
- // Transfers the results from the AsyncCompletedEventArgs and getResult() to the
- // TaskCompletionSource, but only AsyncCompletedEventArg's UserState matches the TCS
- // (this check is important if the same WebClient is used for multiple, asynchronous
- // operations concurrently). Also unregisters the handler to avoid a leak.
- if (e.UserState == tcs)
- {
- if (e.Cancelled) tcs.TrySetCanceled();
- else
if (e.Error != null) tcs.TrySetException(e.Error); - else tcs.TrySetResult(getResult());
- unregisterHandler();
- }
- }
- }
最新文章
- WinForm小白的WPF初试一:从PropertyGrid控件,输出内容到Word(上)
- 让树莓派说出自己的IP地址
- excel中 lookup的使用
- 微信小程序购物商城系统开发系列
- Slideout吐槽
- 编译安装-Apache
- 洛谷 P3374 【模板】树状数组 1
- Gradle – Spring 4 MVC Hello World Example
- html css 笔记
- dojo.hasClass/dojo.addClass/dojo.removeClass/dojo.toggleClass/dojo.repalceClass
- Windows Phone开发(31):画刷
- 关于struts2的web.xml配置
- myeclipse2017下载安装与破解详细教程
- tensorflow object detection api graph rewriter
- Add Inline Actions
- CAN协议教程
- 异常上报工具:腾讯Bugly
- Kaggle泰坦尼克数据科学解决方案
- Shiro 五张表
- typecho开启pjax,ajax,无刷新