码迷,mamicode.com
首页 > 其他好文 > 详细

利用TaskCompletionSource将EAP转换成TAP

时间:2015-09-23 10:30:37      阅读:249      评论:0      收藏:0      [点我收藏+]

标签:

?

?

1.原始的异步方法的调用

?

我们来看个简单的例子,在这里演示调用 WebClient.DownloadStringAsync 方法(这个方法不是 TAP),然后由 WebClient.DownloadStringCompleted 事件通知 UI 更新,这是大多数人都会用的方法。

?

  1. private void DownloadString(string address)
  2. {
  3. ????WebClient wc = new WebClient();
  4. ????wc.DownloadStringCompleted += (sender, e) =>
  5. ????{
  6. ????????if (e.Cancelled)
  7. ????????????this.textBox1.Text = "Cancel";
  8. ????????else if (e.Error != null)
  9. ????????????this.textBox1.Text = "Error";
  10. ????????else
  11. ????????????this.textBox1.Text = e.Result;
  12. ????};
  13. ?
  14. ????wc.DownloadStringAsync(new Uri(address));
  15. }

客户端调用

?

  1. private void button_DownloadString_Click(object sender, EventArgs e)
  2. {
  3. ????DownloadString("https://www.google.com.tw/");
  4. }

这是一个很简单的例子,一旦若项目里有成千上万的通知事件跟 UI 绑在一起,维护起来会相当的痛苦。

?

2.将 EAP 转换成 TAP步骤

?

  • 命名规则以 Async 为后缀
  • 返回 Task 或是 Task<TResult>
  • 调用 TaskCompletionSource 方法

?

改变 Task 状态可调用以下三个方法:SetCanceled、SetException、SetResult

  1. private Task<string> DownloadStringAsync(string address)
  2. {
  3. ????var tcs = new TaskCompletionSource<string>();
  4. ????WebClient wc = new WebClient();
  5. ????wc.DownloadStringCompleted += (sender, e) =>
  6. ????{
  7. ????????if (e.Cancelled)
  8. ????????????tcs.SetCanceled();
  9. ????????else if (e.Error != null)
  10. ????????????tcs.SetException(e.Error);
  11. ????????else
  12. ????????????tcs.SetResult(e.Result);
  13. ????};
  14. ?
  15. ????wc.DownloadStringAsync(new Uri(address));
  16. ????return tcs.Task;
  17. }

?

客户端调用

  1. private async void button_DownloadStringAsync_Click(object sender, EventArgs e)
  2. {
  3. ????var task = DownloadStringAsync("https://www.google.com.tw/");
  4. ????await task;
  5. ????if (task.IsCanceled)
  6. ????{
  7. ????????this.textBox1.Text = "Cancel";
  8. ????}
  9. ????else if (task.IsFaulted)
  10. ????{
  11. ????????this.textBox1.Text = "Error";
  12. ????}
  13. ????else if (task.IsCompleted)
  14. ????{
  15. ????????this.textBox1.Text = task.Result;
  16. ????}
  17. }

?

转自:http://www.it165.net/pro/html/201308/6710.html

?

3.微软的封装

?

  1. public static Task<byte[]> DownloadDataTask(this WebClient webClient, Uri address)
  2. {
  3. ????// Create the task to be returned
  4. ????var tcs = new TaskCompletionSource<byte[]>(address);
  5. ?
  6. ????// Setup the callback event handler
  7. ????DownloadDataCompletedEventHandler handler = null;
  8. ????handler = (sender, e) => EAPCommon.HandleCompletion(tcs, e, () => e.Result, () => webClient.DownloadDataCompleted -= handler);
  9. ????webClient.DownloadDataCompleted += handler;
  10. ?
  11. ????// Start the async work
  12. ????try
  13. ????{
  14. ????????webClient.DownloadDataAsync(address, tcs);
  15. ????}
  16. ????catch(Exception exc)
  17. ????{
  18. ????????// If something goes wrong kicking off the async work,
  19. ????????// unregister the callback and cancel the created task
  20. ????????webClient.DownloadDataCompleted -= handler;
  21. ????????tcs.TrySetException(exc);
  22. ????}
  23. ?
  24. ????// Return the task that represents the async operation
  25. ????return tcs.Task;
  26. }

?

  1. internal class EAPCommon
  2. {
  3. ????internal static void HandleCompletion<T>(
  4. ????????TaskCompletionSource<T> tcs, AsyncCompletedEventArgs e, Func<T> getResult, Action unregisterHandler)
  5. ????{
  6. ????????// Transfers the results from the AsyncCompletedEventArgs and getResult() to the
  7. ????????// TaskCompletionSource, but only AsyncCompletedEventArg‘s UserState matches the TCS
  8. ????????// (this check is important if the same WebClient is used for multiple, asynchronous
  9. ????????// operations concurrently). Also unregisters the handler to avoid a leak.
  10. ????????if (e.UserState == tcs)
  11. ????????{
  12. ????????????if (e.Cancelled) tcs.TrySetCanceled();
  13. ????????????else if (e.Error != null) tcs.TrySetException(e.Error);
  14. ????????????else tcs.TrySetResult(getResult());
  15. ????????????unregisterHandler();
  16. ????????}
  17. ????}
  18. }

利用TaskCompletionSource将EAP转换成TAP

标签:

原文地址:http://www.cnblogs.com/pengzhen/p/4831339.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!