使用委托进行异步编程

1 篇文章 0 订阅
1 篇文章 0 订阅

使用委托可以通过异步方式调用同步方法。当同步调用一个委托时,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 中为 <Out> ByRef 和 ByRef)以及由 BeginInvoke 返回的 IAsyncResult。

 

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            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);

            //}
            Console.Read();
        }

        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;

        }

    }
}
转载地址:http://hi.baidu.com/slcands2/blog/item/f4209c8c60d6f28ea5c27209.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值