c# 异步调用之异步模式
Func<string, IImageRequest, string> downloadString = (address, req) =>
{
var client = new WebClient();
foreach (var header in req.Headers)
{
client.Headers.Add(header.Key, header.Value);
}
client.Credentials = req.Credentials;
client.Encoding = System.Text.Encoding.UTF8;
return client.DownloadString(address);
}; Action<SearchItemResult> addItem = item => _searchInfo.List.Add(item); foreach (var req in GetSearchRequests())
{
downloadString.BeginInvoke(req.Url, req, ar =>//BeginInvoke:线程池中一个线程异步调用
{
try
{
string resp = downloadString.EndInvoke(ar);//downloadString异步方法执行结束,执行ar委托
var images = req.Parse(resp);
foreach (var image in images)
{
this.Dispatcher.Invoke(addItem, image);//当前线程回到主线程同步执行
}
}
catch (WebException ex) when (ex.Message.Contains("401"))
{
MessageBox.Show(errorMessage, "Registration Needed");
}
}, null);
}

  

c#异步调用之基于事件
foreach (var req in GetSearchRequests())
{
var client = new WebClient();
foreach (var header in req.Headers)
{
client.Headers.Add(header.Key, header.Value);
}
client.Credentials = req.Credentials;
client.DownloadStringCompleted += (sender1, e1) =>
{
try
{
string resp = e1.Result;
var images = req.Parse(resp);
foreach (var image in images)
{
_searchInfo.List.Add(image);//事件处理程序可以直接访问UI
}
}
catch (Exception ex) when (ex.InnerException?.Message.Contains("401") ?? false)
{
MessageBox.Show(errorMessage, "Registration Needed");
}
};
client.DownloadStringAsync(new Uri(req.Url));//异步变体方法 以“async”后缀;结束之后会调用事件,此方法对应DownloadStringCompleted事件
}

  

//异步调用之基于任务(TAP)
private async void OnTaskBasedAsyncPattern(object sender, RoutedEventArgs e)//async关键字创建了一个状态机
{
_cts = new CancellationTokenSource();
try
{
foreach (var req in GetSearchRequests())
{
var clientHandler = new HttpClientHandler
{
Credentials = req.Credentials
};
var client = new HttpClient(clientHandler);
foreach (var header in req.Headers)
{
client.DefaultRequestHeaders.Add(header.Key, header.Value);
} var response = await client.GetAsync(req.Url, _cts.Token);//解除线程阻塞
response.EnsureSuccessStatusCode();
string resp = await response.Content.ReadAsStringAsync();//解除线程阻塞
await Task.Run(() =>//后台线程运行
{
var images = req.Parse(resp);
foreach (var image in images)
{
_cts.Token.ThrowIfCancellationRequested();
_searchInfo.List.Add(image);//UI调用问题:BindingOperations.EnableCollectionSynchronization,启用集合同步访问功能
}
}, _cts.Token);
}
}
catch (HttpRequestException ex) when (ex.Message.Contains("401"))
{
MessageBox.Show(errorMessage, "Registration Needed");
}
catch (OperationCanceledException ex)
{
MessageBox.Show(ex.Message);
}
}

  

c# 异步调用(异步模式,基于事件)的更多相关文章

  1. C# 委托的三种调用示例(同步调用 异步调用 异步回调)

    首先,通过代码定义一个委托和下面三个示例将要调用的方法: 复制代码 代码如下: public delegate int AddHandler(int a,int b);    public class ...

  2. 20160711--C# 委托的三种调用示例(同步调用 异步调用 异步回调)【转载】

    首先,通过代码定义一个委托和下面三个示例将要调用的方法: 代码如下: public delegate int AddHandler(int a,int b); public class 加法类 { p ...

  3. C# 同步调用 异步调用 异步回调 多线程的作用

    同步调用   : 委托的Invoke方法用来进行同步调用.同步调用也可以叫阻塞调用,它将阻塞当前线程,然后执行调用,调用完毕后再继续向下进行. 异步调用  :同步调用会阻塞线程,如果是要调用一项繁重的 ...

  4. WCF初探-11:WCF客户端异步调用服务

    前言: 在上一篇WCF初探-10:WCF客户端调用服务 中,我详细介绍了WCF客户端调用服务的方法,但是,这些操作都是同步进行的.有时我们需要长时间处理应用程序并得到返回结果,但又不想影响程序后面代码 ...

  5. 二、基于事件的异步编程模式(EAP)

    一.引言 在上一个专题中为大家介绍了.NET 1.0中提出来的异步编程模式--APM,虽然APM为我们实现异步编程提供了一定的支持,同时它也存在着一些明显的问题--不支持对异步操作的取消和没有提供对进 ...

  6. 深入理解C#中的异步(一)——APM模式EAP模式

    深入理解C#中的异步(一)--APM模式EAP模式 目录 深入理解C#中的异步(一)--APM模式EAP模式 1 使用异步编程的原因 2 异步编程模式 2.1 APM模式 2.1.1 APM模式示例代 ...

  7. 异步和多线程,委托异步调用,Thread,ThreadPool,Task,Parallel,CancellationTokenSource

    1 进程-线程-多线程,同步和异步2 异步使用和回调3 异步参数4 异步等待5 异步返回值 5 多线程的特点:不卡主线程.速度快.无序性7 thread:线程等待,回调,前台线程/后台线程, 8 th ...

  8. Spring Boot中实现异步调用之@Async

    一.什么是异步调用 “异步调用”对应的是“同步调用”,同步调用指程序按照定义顺序依次执行,每一行程序都必须等待上一行程序执行完成之后才能执行:异步调用指程序在顺序执行时,不等待异步调用 的语句返回结果 ...

  9. C#“同步调用”、“异步调用”、“异步回调”

    本文将主要通过“同步调用”.“异步调用”.“异步回调”三个示例来讲解在用委托执行同一个“加法类”的时候的的区别和利弊. 首先,通过代码定义一个委托和下面三个示例将要调用的方法: ); //模拟该方法运 ...

  10. C#委托的异步调用1

    本文将主要通过“同步调用”.“异步调用”.“异步回调”三个示例来讲解在用委托执行同一个“加法类”的时候的的区别和利弊. 首先,通过代码定义一个委托和下面三个示例将要调用的方法: /*添加的命名空间 u ...

随机推荐

  1. WPF 精修篇 属性动画

    原文:WPF 精修篇 属性动画 属性动画 是通过 Storyboard 来改变属性值 <Rectangle x:Name="rect" Width="200&quo ...

  2. C# 递增操作符 ++ --

    记混了好几次,记录一下 递增操作符出现在操作数之前:先递增后赋值 ; int result; result =++count; Console.WriteLine($"count:{coun ...

  3. 自定义Robotframework,Appium的一个关键字(用于点击目标图片,用于Appium无法识别的一些图片元素)

     Appium无法识别的一些图片元素,必须先通过图片找坐标,进而通过点击坐标解决问题. 1.先在terminer运行安装命令: pip install robotframework-appiumlib ...

  4. ES6 变量与解构(二)

    一.变量的声明与使用 [测试示例需要在node环境中测试,浏览器环境下并不完全兼容ES6代码]ES6中可以使用 {} 来包含任意一段代码,被 {} 包裹的内容称为一个代码块(局部作用域) let关键字 ...

  5. Test CMake run finished with errors

    Test CMake run finished with errors 记录一个安装 CLion 过程中的错误. CLion的安装和破解教程网上有很多,大家可以自行搜索. 安装了之后在 Setting ...

  6. loadrunner安装和应用

    问题:1.负载测试流程 2.为什么实现性能测试自动化 3.设置场景  (场景定义) 4.事物响应时间,吞吐量和吞吐率,正在运行vuser,windows资源,每秒点击次数,每秒http响应数. 5.i ...

  7. Java面经入口(持续更新...)

     大数据面经 https://zhuanlan.zhihu.com/go-for-it Java 基础知识复习 您可能不知道Java基础40道常见面试题及详细答案 hashcode详解 Java St ...

  8. thinkphp整合系列之极验滑动验证码geetest

    给一个央企做官网,登录模块用的thinkphp验证码类.但是2019-6-10到12号,国家要求央企检验官网漏洞,防止黑客攻击,正直贸易战激烈升级时期,所以各事业单位很重视官网安全性,于是乎集团总部就 ...

  9. Linux C/C++编译过程中的各种not declared in this scope

    Linux C/C++编译时经常会"XXX was not declared in this scope" 原因可能是以下几种: 变量名或函数名写错了; 忘记定义了 没有成功链接到 ...

  10. Django框架(三)-- orm增删改查、Django生命周期

    一.orm介绍 1.什么是orm ORM即Object Relational Mapping,全称对象关系映射. 2.使用orm的优缺点 优点: 不用写SQL语句 开发效率高 缺点: SQL的效率低 ...