Chinaunix首页 | 论坛 | 博客
  • 博客访问: 165612
  • 博文数量: 36
  • 博客积分: 2160
  • 博客等级: 大尉
  • 技术积分: 382
  • 用 户 组: 普通用户
  • 注册时间: 2007-03-27 01:48
个人简介

喝喝咖啡,做做开发

文章分类
文章存档

2014年(4)

2013年(1)

2012年(4)

2011年(2)

2010年(3)

2009年(9)

2008年(3)

2007年(10)

我的朋友

分类: 嵌入式

2007-08-30 16:41:52

    异步调用在C#中的应用浅析
作者:山东人在成都
    当同步调用一项很耗资源的运算时,整个应用程序,看起来就像死掉一样,在运算结束前不会有任何响应.任何一 个程序设计者都不希望发生这样的事,除非是必须.
    解决的一个好办法,就是让一个另外的线程去执行那项消耗资源的运算,而不妨碍主线程的正常运行..NET  Framework提供了异步调用,它需要定义与需要调用的方法具有相同签名的委托,实质上.NET通过委托将所调用的方 法置于新线程上运行.如果不想有线程调用的烦琐,异步调用是不错的选择.
    委托为异步调用提供了BeginInvoke和EndInvoke方法.BeginInvoke方法用于启动异步调用,它包含有与异步执 行的方法相同的参数,并且还有另外两个参数AsyncCallback callback和object asyncState,启动后BeginInvoke会 立即返回,不等待异步调用完成,返回IAsyncResult,用以监视调用进度. EndInvoke方法用于检索异步调用结果,如 果异步调用尚未完成,EndInvoke将一直阻塞至异步调用完成.EndInvoke的参数除了委托调用的异步方法的out或ref 参数外,还有BeginInvoke方法返回的IAsyncResult.
    经常使用的异步调用方法有四种,即在调用BeginInvoke后经常有四种方式进行后续处理.
    第一种方式最简单,调用BeginInvoke后,直接调用EndInvoke方法,这将一直阻塞到方法运算结束.
    第二种方式使用IAsyncResult.AsyncWaitHandle取得WaitHandle,并使用它的WaitOne方法将执行一直阻塞到发 出WaitHandle信号,然后调用EndInvoke.
    第三种方式是轮询由BeginInvoke返回的IAsyncResult,确定异步调用完成然后再调用EndInvoke.在轮询过程中 ,可以处理其他事务,或者更新界面部分.
    第四种方式是将回调方法的委托传递给BeginInvoke,该方法在异步调用完成后在线程池上执行,该回调方法可 以调用EndInvoke.
    第一,二种方式,仍然会使主程序停止响应,看起来就像是同步调用,没有预期的效果,第三种方式则very good, 异步调用后,该做什么事就做什么事,第四种方式没有测试,不知道效果如何.
    附加测试代码:
   

using System;
public class TestAsync
{
 delegate string MethodDelegate();
 private string TestCallMethod()
 {
  Console.WriteLine("async method");
  return "hello";
 }
 public void AsyncCall1()
 {
  MethodDelegate md = new MethodDelegate(this.TestCallMethod);
  IAsyncResult ar = md.BeginInvoke(null, null);
  string s = md.EndInvoke(ar);
  Console.WriteLine(s);
 }
 public void AsyncCall2()
 {
  MethodDelegate md = new MethodDelegate(this.TestCallMethod);
  IAsyncResult ar = md.BeginInvoke(null, null);
  ar.AsyncWaitHandle.WaitOne();
  string s = md.EndInvoke(ar);
  Console.WriteLine(s);
 }
 public void AsyncCall3()
 {
  MethodDelegate md = new MethodDelegate(this.TestCallMethod);
  IAsyncResult ar = md.BeginInvoke(null, null);
  while (!ar.IsCompleted)
  {
   //该做啥事做啥事

  }
  string s = md.EndInvoke(ar);
  Console.WriteLine(s);
 }
 public static void Main()
 {
  TestAsync ta = new TestAsync();
  ta.AsyncCall();
 }
}

阅读(1289) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

MaxWillKe2008-09-02 11:24:05

实质上.NET通过委托将所调用的方 法置于新线程上运行. 方法三中我加入了Thread.CurrentThread();在异步调用中和执行后却是同一线程名?请问...