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 精修篇 调用Win32Api

    原文:WPF 精修篇 调用Win32Api 栗子是 调用WIn32API 让窗口最前 后台代码 [DllImport("user32.dll")] private static e ...

  2. Ubuntu Nginx https 配置

    #配置http跳转到https 80跳转443server { listen ; server_name www.***.com www.***.cn; https://$server_name$re ...

  3. Kafka分区分配策略-RangeAssignor、RoundRobinAssignor、StickyAssignor

    引言按照Kafka默认的消费逻辑设定,一个分区只能被同一个消费组(ConsumerGroup)内的一个消费者消费.假设目前某消费组内只有一个消费者C0,订阅了一个topic,这个topic包含7个分区 ...

  4. kafka源码导入idea/eclipse

    先进入源码工程:执行gradle idea或者gradle eclipse 之后再导入idea/eclipse

  5. 快捷键-Visual Studio Code快捷键

    Shift+Enter 在Python终端中运行选定内容/行 C

  6. c#ADO.NET 执行带参数及有返回数据

    直接上代码,这个过程中有个数据SqlDataReader转为 DataTable的过程,当中为什么这样,是应为我直接绑定DataSource的时候没有数据,网人家说直接绑定但是没效果,我就转换了一下. ...

  7. Spring Cloud入门

    Spring Cloud为开发者开发分布式应用提供了便捷工具(包括配置管理.服务发现.断路器.智能路由.微服务代理.控制总线.一次性令牌.全局锁.领导者选举.分布式会话.集群状态等).为开发分布式应用 ...

  8. 让Linux中的Nginx支持中文文件名

    原文:https://blog.csdn.net/soeben/article/details/79525964 首先你的服务器需要安装了UTF-8字符集在命令行里输入env|grep LANG如果显 ...

  9. np.append()

    1.numpy.append() np.append(arr,values,axis=None) 功能:在array后面追加values 参数: arr:array_like 值将附加到此数组的副本. ...

  10. django rest framework 认证组件

    1.认证组件 1.认证组件 1.认证组件 1.认证组件