ChangeWorld
——科技改变世界

  最近在做一个项目中用到了回调函数,对其理解不是十分清晰,于是在网上搜了一下,研究了一番,终于理解稍稍透彻一些,共享出来,希望对后来人有所帮助。

  首先要感谢  使用 AsyncCallback 处理异步调用  一文,受这篇文章的启发,加之msdn 上的定义和举例,我清晰地理解了回调函数的机制。

先把原帖发出来,作为参考,再次感谢这位博主的无私帮助精神。

 

参考文章 原文

异步调用可以避免主线程受工作线程阻塞,即工作线程执行的过程中,主线程依然可以往下运行,不必等待工作线程完成。下面是一个简单的异步调用加法函数的例子。

using System;
using System.Threading;
// the namespace for AsyncResult.
using System.Runtime.Remoting.Messaging;

namespace AsyncCallback
{
// Delegate for add method.
public delegate int TwoOperands(int a,int b);

class Program
{
static void Main(string[] args)
{
Console.WriteLine("Main is running on thread " + Thread.CurrentThread.ManagedThreadId);
TwoOperands operation = new TwoOperands(Add);
//async calling the add.
//new System.AsyncCallback(CallbackHandler) 回调处理函数, 异步调用结束后,runtime会调用该函数。
// "Async parameter" 作为回调参数,传给回调函数,通过 AsyncResult.AsyncState 获取
operation.BeginInvoke(2, 3, new System.AsyncCallback(CallbackHandler), "Async parameter");
Console.WriteLine("Main is running on thread " + Thread.CurrentThread.ManagedThreadId);
Console.Read();
}

/// <summary>
/// 回调处理函数
/// </summary>
/// <param name="iar">回调参数</param>
static void CallbackHandler(IAsyncResult iar)
{
Console.WriteLine("CallbackHandler is running on thread " + Thread.CurrentThread.ManagedThreadId);
AsyncResult ar = (AsyncResult)iar;
// 获取原委托对象。
TwoOperands operation = (TwoOperands)ar.AsyncDelegate;
// 结束委托调用。
int i = operation.EndInvoke(iar);
// 打印异步调用传入的参数。
Console.WriteLine("The Async calling parameter is " + ar.AsyncState);
Console.WriteLine("The adding result is " + i);
}

static int Add(int i, int j)
{
Console.WriteLine("Add is running on thread " + Thread.CurrentThread.ManagedThreadId + "...");
Thread.Sleep(5000);
return i + j;
}
}
}

输出结果

                       

由此可见,异步调用的函数,与异步回调函数是在同一线程上运行的。

分类: C#/Net

标签: AsyncCallback 异步调用

 

 

  这位博主在文章开头将回调函数的作用和优势做了简单的描述,简明扼要,通俗易懂。

  加上我的理解:在线程执行一个任务时,主线任务需要另外一个计算结果作为参数,为了使主线程不间断的执行主线任务,开辟另外一个线程去完成这一计算结果,完成后将这一计算结果回传给主线程。这样就实现了主线程不间断地执行主线任务,使得主线程专注于主线任务的处理,将琐碎的任务交由其他线程去做,命令其做完后把结果交还给主线程。小可认为回调函数是由分线程处理完成后将执行结果回传给主线程,这一回传的动作得名,名之曰,回调函数。或许不对,希望大家斧正。

         从代码流程可以清晰看到,主线程在执行期间一直未被打断(线程ID为9),线程执行完毕后,执行委托的Add方法(线程ID为10),该Add 方法的返回值赋予iar,之后调用回调函数CallbackHandler(线程ID为10),通过ar.AsyncDelegate 获取委托对象执行结束委托调用,获取返回值。回调函数还提供了一个参数(最后一个参数)用来传递希望传递的值(该参数可缺省),通过ar.AsyncState 获取。黑屏打印信息提示调用委托的Add方法和调用回调函数用的是同一个线程ID(线程ID都为10)。这说明这个分线程先执行了委托的Add方法,随即执行了那个回调函数。

 

posted on 2011-11-25 09:38  ChangeWorld  阅读(1583)  评论(0编辑  收藏  举报