DotNET异步编程

来源:互联网 发布:sql 实现累加 编辑:程序博客网 时间:2024/05/15 23:49

DotNET异步编程

一.如何理解异步编程
使用 .NET 异步编程,在程序继续执行的同时对 .NET 类方法进行调用,直到进行指定的回调为止;
如果没有提供回调,则直到对调用的阻塞、轮询或等待完成为止。
例如,一个程序可以调用一个方法,该方法枚举一个较大的列表,同时主程序将继续执行。在完成枚举后,进行回调并由程序对它进行寻址。
二.使用异步编程的领域
文件IO 流IO 套接字IO
远程处理信道(HTTP、TCP)和代理
使用 ASP.NET 创建的 XML Web services
ASP.NET Web 窗体
使用 MessageQueue 类的消息队列
异步委托
三.如何进行进行异步调用?
.NET Framework 允许异步调用任何方法。
定义需要调用的方法具有相同签名的委托
公共语言运行库将自动为该委托定义具有适当签名的 BeginInvoke 和 EndInvoke 方法。
四.委托与传统的函数指针的区别
委托是安全的面向对象的函数指针,为了加深对此的理解,分别用C++实现一个函数指针和C#实现一个委托,见例1和例2.
五.Delegate类、MulticastDelegate和delegate关键字介绍
重点是Invoke、BeginInvoke 和 EndInvoke方法以及参数的含义
六.IAsyncResult接口
IAsyncResult 接口用于监视和管理异步操作。该接口是从开始操作返回的并被传递到结束操作,以将开始操作和结束操作相关联。如果回调被
指定为开始操作的一部分,则 AsyncResult 被传递到回调。它的四个属性如下:
AsyncState :返回在开始操作方法调用中作为最后一个参数提供的对象。
AsyncWaitHandle :返回 WaitHandle,后者可用于执行 WaitHandle.WaitOne、WaitAny 或 WaitAll。
CompletedSynchronously :如果开始操作调用已同步完成,则 CompletedSynchronously 属性将被设置为 true。
IsCompleted :在服务器已处理完调用后,IsCompleted 属性将被设置为 true。
七.四种异步编程方法
调用BeginInvoke后,有四种选择:
(1)进行某些操作,然后调用 EndInvoke 一直阻塞到调用完成。 (见例3)
(2)使用 IAsyncResult.AsyncWaitHandle 获取 WaitHandle,使用它的     WaitOne 方法将执行一直阻塞到发出
WaitHandle 信号,然后
调用 EndInvoke。(见例4)
(3)轮询由 BeginInvoke 返回的 IAsyncResult,确定异步调用何时完成,然后调用 EndInvoke。(见例5)
(4)将用于回调方法的委托传递给 BeginInvoke。该方法在异步调用完成后在 ThreadPool 线程上执行,它可以调用 EndInvoke。(见例6

注意:始终在异步调用完成后调用 EndInvoke。
八.Webservice异步调用、远程对象异步调用、异步Socket的实现,代码取自MSDN
九.代码部分
例(1)
////////////////////////////////////////
#include <iostream.h>
typedef int CFun(int);
void FunTest(CFun * f,int i)
{
 cout<<f(i)<<endl;
}
int Fun1(int i)
{
 return i;
}
int Fun2(int i,int j)
{
 return i+j;
}
int main()
{
 FunTest((CFun *)Fun1,5);
 FunTest((CFun *)Fun2,3);//可以通过编译,运行时产生不可预知的结果
 return 0;
}
///////////////////////////////////////
例(2)
///////////////////////////////////////
using System;
namespace DelegateTest
{
 public delegate int MyDelegate1(int i);
 public delegate int MyDelegate2(int i,int j);
 public delegate int MyDelegate3(int i,int j,int k);
 class ClassMain
 {
  [STAThread]
  static void Main(string[] args)
  {
   ClassMain cm=new ClassMain();
   MyDelegate1 md1=new MyDelegate1(cm.Fun1);
   int n=md1(10);
   Console.WriteLine(n);
   MyDelegate2 md2=new MyDelegate2(cm.Fun2);
   n=md2(10,100);
   Console.WriteLine(n);
   //错误的代码,委托和函数签名不匹配,不能通过编译
   //md=new MyDelegate(cm.Fun2);
  }
  private int Fun1(int i)
  {
   return i;
  }
  private int Fun2(int i,int j)
  {
   return i+j;
  }
 }
}
///////////////////////////////////////
例(3)
///////////////////////////////////////
using System;
using System.Threading;
namespace AsyTest1
{
 public delegate void MyDelegate();
 class ClassMain
 {
  [STAThread]
  static void Main(string[] args)
  {
   MyDelegate md=new MyDelegate(Fun);
   IAsyncResult ar=md.BeginInvoke(null,null);
   int i=1;
   //调用线程模拟正在做一些操作
   while(i<1000000000)
   {
    i+=2;
    i-=1;
   }
   Console.WriteLine("调用线程的工作做完了,下面等待异步调用完成");
   md.EndInvoke(ar);
   Console.WriteLine("程序结束");
  }
  static void Fun()
  {
   //模拟正在进行一些耗时操作,比如检索文件
   Thread.Sleep(10000);
   Console.WriteLine("Fun执行完毕");
  }
 }
}
//////////////////////////////////////
例(4)
//////////////////////////////////////
using System;
using System.Threading;
namespace AsyTest2
{
 public delegate int MyDelegate(int i,int j);
 class ClassMain
 {
  [STAThread]
  static void Main(string[] args)
  {
   MyDelegate md=new MyDelegate(Fun);
   IAsyncResult ar=md.BeginInvoke(10,20,null,null);
   //使用等待句柄
   ar.AsyncWaitHandle.WaitOne();
   Console.WriteLine("等待结束");
   int k=md.EndInvoke(ar);
   Console.WriteLine("程序结束,k={0}",k);
  }
  static int Fun(int i,int j)
  {
   //模拟正在进行一些耗时操作,比如检索文件
   Thread.Sleep(10000);
   Console.WriteLine("Fun执行完毕");
   return i+j;
  }
 }
}
//////////////////////////////////////
例(5)
//////////////////////////////////////
using System;
using System.Threading;
namespace AsyTest3
{
 public delegate int MyDelegate(int i,int j);
 class ClassMain
 {
  [STAThread]
  static void Main(string[] args)
  {
   MyDelegate md=new MyDelegate(Fun);
   IAsyncResult ar=md.BeginInvoke(10,20,null,null);
   while(ar.IsCompleted==false)
   {
    //模拟正在做一些其他操作
    Console.WriteLine(".....");
    Thread.Sleep(2000);
   }
   Console.WriteLine("轮询结束");
   int k=md.EndInvoke(ar);
   Console.WriteLine("程序结束,k={0}",k);
  }
  static int Fun(int i,int j)
  {
   //模拟正在进行一些耗时操作,比如检索文件
   Thread.Sleep(10000);
   Console.WriteLine("Fun执行完毕");
   return i+j;
  }
 }
}
//////////////////////////////////////
例(6)
//////////////////////////////////////
using System;
using System.Threading;
namespace AsyTest4
{
 public delegate int MyDelegate(int i,int j);
 class ClassMain
 {
  [STAThread]
  static void Main(string[] args)
  {
   MyDelegate md=new MyDelegate(Fun);
   //启动异步调用,指定回调函数CallBack
   IAsyncResult ar=md.BeginInvoke(10,20,new AsyncCallback(CallBack),md);
   //主函数继续执行其他操作
   Thread.Sleep(5000);
   Console.WriteLine("主函数的操作完成");
   //避免主函数在Fun之前结束
   Console.ReadLine();
  }
  static int Fun(int i,int j)
  {
   //模拟正在进行一些耗时操作,比如检索文件
   Thread.Sleep(10000);
   return i+j;
  }
  static void CallBack(IAsyncResult ar)
  {
   //获取主函数中的md对象引用
   MyDelegate md=(MyDelegate)ar.AsyncState;
   int k=md.EndInvoke(ar);
   Console.WriteLine("Fun执行完毕,回调函数执行,结果={0}",k);
  }
 } 

原创粉丝点击