深入浅出多线程系列之六:事件驱动异步模式(EAP,WebClient,BackgroundWorker)

简介:

Event-based asynchronous(EAP)在多线程的环境中提供了一个简单的处理方式。

它有以下几个特性:

 

  1. 支持取消。
  2. 可以安全的更新WPFwindows Forms 控件。
  3. completion event中可以查询异常信息。
  4. “在后台”执行耗时任务(例如下载和数据库操作),但不会中断您的应用程序。

  5. 同时执行多个操作,每个操作完成时都会接到通知。

  6. 等待资源变得可用,但不会停止(“挂起”)您的应用程序。

  7. 使用熟悉的事件和委托模型与挂起的异步操作通信。 

EAP仅仅只是一个模式而已。,所以这些特性必须都由实现者来实现。在Framework中有少数几个类支持这种模式,最著名的就是BackgroundWorkerSystem.Net.WebClient 了。

这个模式的本质是:每个类都提供了一些相似的成员来管理多线程,例如:

 

public byte[] DownloadData(Uri address);

public void DownloadDataAsync(Uri address);

public void DownloadDataAsync(Uri address, object userToken);

public event DownloadDataCompletedEventHandler DownloadDataCompleted;

 

public void CancelAsync(); //取消操作

public bool IsBusy { get; } //获取是否正在运行的信息。

 

下面是使用WebClient 的例子:

复制代码
var wc  =   new  WebClient();
            wc.DownloadStringCompleted 
+=  (sender, args)  =>
                {
                    
if  (args.Cancelled)
                        Console.WriteLine(
" Canceled " );
                    
else   if  (args.Error  !=   null )
                        Console.WriteLine(
" Exception: "   +  args.Error.Message);
                    
else
                    {
                        Console.WriteLine(args.Result.Length 
+   "  chars were downloaded " );
                    }
                };
            wc.DownloadStringAsync(
new  Uri( " http://www.cnblogs.com/LoveJenny/ " ));
复制代码

 

一个WebClient虽然有多个异步方法,但是因为它们都共享了相同的CancelAsync IsBusy属性,所以一次只能有一个异步操作。

 

BackgroundWorker

BackgroundWorkerSystem.ComponentModel下面的一个管理工作线程的帮助类,提供了下面几个特性

  1. 支持取消。
  2. 可以安全的更新WPFwindows Forms 控件。
  3. completion event中可以查询异常信息。
  4. 可以报告进度。
  5. 因为实现了IComponent接口,所以可以被设计器使用。
  6. BackgroundWorker使用了线程池,这意味着你永远都不能在一个BackgroundWorker线程上调用Abort方法
复制代码
static  BackgroundWorker _bw  =   new  BackgroundWorker();

        
public   static   void  MainThread()
        {
            _bw.DoWork 
+=   new  DoWorkEventHandler(_bw_DoWork);
            _bw.RunWorkerAsync(
" Message to worker " );
            Console.ReadLine();
        }

        
static   void  _bw_DoWork( object  sender, DoWorkEventArgs e)
        {
            Console.WriteLine(e.Argument);
            
// 做一些耗时的操作。
        }
复制代码

 

下面的例子实现了进度报告。

复制代码
class  ThreadBackgroundWorker
    {
        
static  BackgroundWorker _bw;

        
public   static   void  MainThread()
        {
            _bw 
=   new  BackgroundWorker
            {
                WorkerReportsProgress 
=   true ,   // 允许报告进度
                WorkerSupportsCancellation  =   true    // 允许取消
            };

            _bw.DoWork 
+=   new  DoWorkEventHandler(_bw_DoWork);
            _bw.ProgressChanged 
+=   new  ProgressChangedEventHandler(_bw_ProgressChanged);
            _bw.RunWorkerCompleted 
+=   new  RunWorkerCompletedEventHandler(_bw_RunWorkerCompleted);

            _bw.RunWorkerAsync(
" Hello to worker " );
            Console.WriteLine(
" Press Enter in the next 5 seconds to cancel. " );
            Console.ReadLine();
            
            
if  (_bw.IsBusy) _bw.CancelAsync();
            Console.ReadLine();
        }

        
static   void  _bw_RunWorkerCompleted( object  sender, RunWorkerCompletedEventArgs e)
        {
            
if  (e.Cancelled)        // 是否取消
                Console.WriteLine( " You canceled! " );
            
else   if  (e.Error  !=   null )   // 是否有异常
                Console.WriteLine( " Worker exception: "   +  e.Error.ToString());
            
else
                Console.WriteLine(
" Complete: "   +  e.Result);
        }

        
static   void  _bw_ProgressChanged( object  sender, ProgressChangedEventArgs e)
        {
          
// 输出进度报告
            Console.WriteLine( " Reached  "   +  e.ProgressPercentage  +   " % " );
        }

        
static   void  _bw_DoWork( object  sender, DoWorkEventArgs e)
        {
            
for  ( int  i  =   0 ; i  <=   100 ; i  +=   20 )
            {
                
if  (_bw.CancellationPending) { e.Cancel  =   true return ; }
                _bw.ReportProgress(i);   
// 报告进度
                Thread.Sleep( 1000 );
            }

            e.Result 
=   123 ;
        }
    }
复制代码

 

 






本文转自LoveJenny博客园博客,原文链接:http://www.cnblogs.com/LoveJenny/archive/2011/05/25/2053688.html,如需转载请自行联系原作者
目录
相关文章
|
17天前
|
SQL 数据建模 BI
【YashanDB 知识库】用 yasldr 配置 Bulkload 模式作单线程迁移 300G 的业务数据到分布式数据库,迁移任务频繁出错
问题描述 详细版本:YashanDB Server Enterprise Edition Release 23.2.4.100 x86_64 6db1237 影响范围: 离线数据迁移场景,影响业务数据入库。 外场将部分 NewCIS 的报表业务放到分布式数据库,验证 SQL 性能水平。 操作系统环境配置: 125G 内存 32C CPU 2T 的 HDD 磁盘 问题出现的步骤/操作: 1、部署崖山分布式数据库 1mm 1cn 3dn 单线启动 yasldr 数据迁移任务,设置 32 线程的 bulk load 模式 2、观察 yasldr.log 是否出现如下错
|
1月前
|
缓存 安全 Java
面试中的难题:线程异步执行后如何共享数据?
本文通过一个面试故事,详细讲解了Java中线程内部开启异步操作后如何安全地共享数据。介绍了异步操作的基本概念及常见实现方式(如CompletableFuture、ExecutorService),并重点探讨了volatile关键字、CountDownLatch和CompletableFuture等工具在线程间数据共享中的应用,帮助读者理解线程安全和内存可见性问题。通过这些方法,可以有效解决多线程环境下的数据共享挑战,提升编程效率和代码健壮性。
68 6
|
2月前
|
监控 Java
java异步判断线程池所有任务是否执行完
通过上述步骤,您可以在Java中实现异步判断线程池所有任务是否执行完毕。这种方法使用了 `CompletionService`来监控任务的完成情况,并通过一个独立线程异步检查所有任务的执行状态。这种设计不仅简洁高效,还能确保在大量任务处理时程序的稳定性和可维护性。希望本文能为您的开发工作提供实用的指导和帮助。
128 17
|
3月前
|
缓存 安全 Java
【JavaEE】——单例模式引起的多线程安全问题:“饿汉/懒汉”模式,及解决思路和方法(面试高频)
单例模式下,“饿汉模式”,“懒汉模式”,单例模式下引起的线程安全问题,解锁思路和解决方法
|
5月前
|
安全 调度 C#
STA模型、同步上下文和多线程、异步调度
【10月更文挑战第19天】本文介绍了 STA 模型、同步上下文和多线程、异步调度的概念及其优缺点。STA 模型适用于单线程环境,确保资源访问的顺序性;同步上下文和多线程提高了程序的并发性和响应性,但增加了复杂性;异步调度提升了程序的响应性和资源利用率,但也带来了编程复杂性和错误处理的挑战。选择合适的模型需根据具体应用场景和需求进行权衡。
|
5月前
|
网络协议 安全 Java
难懂,误点!将多线程技术应用于Python的异步事件循环
难懂,误点!将多线程技术应用于Python的异步事件循环
144 0
|
5月前
|
编解码 数据安全/隐私保护 计算机视觉
Opencv学习笔记(十):同步和异步(多线程)操作打开海康摄像头
如何使用OpenCV进行同步和异步操作来打开海康摄像头,并提供了相关的代码示例。
231 1
Opencv学习笔记(十):同步和异步(多线程)操作打开海康摄像头
|
6月前
|
设计模式 缓存 Java
谷粒商城笔记+踩坑(14)——异步和线程池
初始化线程的4种方式、线程池详解、异步编排 CompletableFuture
|
7月前
|
Java 数据库
异步&线程池 CompletableFuture 异步编排 实战应用 【终结篇】
这篇文章通过一个电商商品详情页的实战案例,展示了如何使用`CompletableFuture`进行异步编排,以解决在不同数据库表中查询商品信息的问题,并提供了详细的代码实现和遇到问题(如图片未显示)的解决方案。
异步&线程池 CompletableFuture 异步编排 实战应用 【终结篇】
|
7月前
|
Java
异步&线程池 CompletableFuture 异步编排 【下篇】
这篇文章深入探讨了Java中的`CompletableFuture`类,解释了如何创建异步操作、使用计算完成时的回调方法、异常处理、串行化方法、任务组合以及多任务组合的使用方式,并通过代码示例展示了各种场景下的应用。
异步&线程池 CompletableFuture 异步编排 【下篇】

热门文章

最新文章