使用委托进行异步编程与异步编程设计模式差不多。可以参考前一篇文章

异步编程设计模式 http://cnn237111.blog.51cto.com/2359144/543937

 

使用委托进行异步编程

.NET Framework 4
 
 
其他版本
 
 

 

使用委托可以通过异步方式调用同步方法。 当同步调用一个委托时,Invoke 方法直接调用对当前线程的目标方法。 如果调用 BeginInvoke 方法,则公共语言运行时 (CLR) 会对请求进行排队并立即返回到调用方。 会对来自线程池的线程异步调用目标方法。 提交请求的原始线程自由地继续与目标方法并行执行。 如果在对 BeginInvoke 方法的调用中指定了回调方法,则当目标方法结束时将调用该回调方法。 在回调方法中,EndInvoke 方法获取返回值和所有输入/输出参数或仅供输出参数。 如果在调用BeginInvoke 时未指定任何回调方法,则可以从调用 BeginInvoke 的线程中调用 EndInvoke

 

 

.NET Framework 允许您异步调用任何方法。为此,应定义与您要调用的方法具有相同签名的委托;公共语言运行库会自动使用适当的签名为该委托定义 BeginInvoke 和 EndInvoke 方法。

BeginInvoke 方法可启动异步调用。它与您需要异步执行的方法具有相同的参数,另外它还有两个可选参数。第一个参数是一个 AsyncCallback 委托,该委托引用在异步调用完成时要调用的方法。第二个参数是一个用户定义的对象,该对象可向回调方法传递信息。BeginInvoke 立即返回,不等待异步调用完成。BeginInvoke 会返回IAsyncResult,这个结果可用于监视异步调用进度。

EndInvoke 方法检索异步调用的结果。调用 BeginInvoke 后可随时调用 EndInvoke 方法;如果异步调用尚未完成,EndInvoke 将一直阻止调用线程,直到异步调用完成后才允许调用线程执行。EndInvoke 的参数包括您需要异步执行的方法的 out 和 ref 参数(在 Visual Basic 中为  ByRef 和 ByRef)以及由 BeginInvoke 返回的 IAsyncResult。

注意

Visual Studio 2005 中的 IntelliSense 功能显示 BeginInvoke 和 EndInvoke 的参数。如果您没有使用 Visual Studio 或类似工具,或您使用的是带有 Visual Studio 2005 的 C#,请参见异步编程概述以获取为这些方法定义的参数的说明。

 

 

class Program

    {

        static void Main()

        {

            Action<int, int> action = (x, y) =>

            {

                for (int i = x; i <= y; i++)

                    if (IsPrimeNumber(i))

                        Console.Write(i + ",");

            };

             Console.WriteLine("synchronous");

            action.Invoke(1000, 1500);//synchronous

             Console.WriteLine("\nno block");

            IAsyncResult result = action.BeginInvoke(1000, 1500, null, null);

             Console.WriteLine("\nAsyncWaitHandle.WaitOne()");

            IAsyncResult result0 = action.BeginInvoke(1000, 1500, null, null);

            result0.AsyncWaitHandle.WaitOne();

             Console.WriteLine("\nEndInvoke");

            IAsyncResult result1 = action.BeginInvoke(1000, 1500, null, null);

            action.EndInvoke(result1);

              Console.WriteLine("\nWhile loop");

            IAsyncResult result2 = action.BeginInvoke(1000, 1500, null, null);

            while (!result2.IsCompleted)//do nothing until it finishes

            {

                Console.Write(".");

                Thread.Sleep(500);

            }

              Console.WriteLine("\ncall mycallback");

            IAsyncResult result3 = action.BeginInvoke(1000, 1500, mycallback, DateTime.Now.ToString("HH:mm:ss:fffffff"));

            Thread.Sleep(2000);//guarantee the async callback function works before the main thread finishes

            //while (!iresult.IsCompleted)//do nothing until it finishes

            //{

            //    Console.Write(".");

            //    Thread.Sleep(500);

            //}

              Console.WriteLine("\nlamuda");

            IAsyncResult result4 = action.BeginInvoke(1000, 1500, (r) =>

            {

                string d = (string)r.AsyncState;

                Console.WriteLine("\r\n{0},finished and call mycallback,now:{1}", d, DateTime.Now.ToString("HH:mm:ss:fffffff"));

            }, DateTime.Now.ToString("HH:mm:ss:fffffff"));

            Thread.Sleep(2000);//guarantee the async callback function works before the main thread finishes

            //while (!iresult.IsCompleted)//do nothing until it finishes

            //{

            //    Console.Write(".");

            //    Thread.Sleep(500);

            //}

          }

          static void mycallback(IAsyncResult result)

        {

            string d = (string)result.AsyncState;

            Console.WriteLine("\r\n{0},finished and call mycallback,now:{1}", d, DateTime.Now.ToString("HH:mm:ss:fffffff"));

        }

          static bool IsPrimeNumber(int n)

        {

            bool b = true;

            if (n == 1)

                b = false;

            else if (n == 2)

                b = true;

            else

            {

                int sqr = Convert.ToInt32(Math.Sqrt(n));

                for (int i = sqr; i >= 2; i--)

                {

                    if (n % i == 0)

                    {

                        b = false;

                    }

                }

            }

            return b;

        }

    }