C#基础之--线程、任务和同步:一、异步委托

创建线程的一种简单方式是定义一个委托,并异步调用它。委托是方法的类型安全的引用。

Delegate还支持异步地调用方法。在后台Delegate类会创建一个执行任务的线程。

为了说明委托的异步特性,从一个需要一定的时间才能执行完毕的方法开始。 TakesAWhile方法至少需要经过第2个变量传递的毫秒数才能执行完,因 为它调用了Thread.Sleep()方法。

复制代码
static int TakesAWhile(int data, int ms)
        {
            Console.WriteLine("TakesAWhile,start");
            Thread.Sleep(ms);
            Console.WriteLine("\nTakesAWhile complated");
            return ++data;
        }
复制代码

要从委托中调用这个方法 ,必须定义一个有相同参数和返回类型的委托 ,如下面的TakesAWhileDelegate方法所示: 

public delegate int TakesAWhileDelegate(int data,int ms);

现在可以使用不同的技术异步地调用委托,并返回结果。

1、投票

复制代码
static void Main(string[] args)
        {
            TakesAWhileDelegate d1 = TakesAWhile;
            IAsyncResult ar = d1.BeginInvoke(1, 5000, null, null);
            while (!ar.IsCompleted)
            {
                Console.Write(".");
                Thread.Sleep(50);
            }

            int result = d1.EndInvoke(ar);
            Console.WriteLine("result:{0}", result);
            Console.ReadKey();
        }
复制代码

运行结果:

.TakesAWhile,start
................................................
TakesAWhile complated
result:2

2、等待句柄

复制代码
static void Main(string[] args)
        {
            TakesAWhileDelegate d1 = TakesAWhile;
            IAsyncResult ar = d1.BeginInvoke(1, 5000, null, null);
            while (true)
            {
                Console.Write(".");
                if (ar.AsyncWaitHandle.WaitOne(50, false))
                {
                    Console.WriteLine("\nCan get the result now");
                    break;
                }
            }

            int result = d1.EndInvoke(ar);
            Console.WriteLine("result:{0}", result);
            Console.ReadKey();
        }
复制代码

3、异步回调

复制代码
class Program
    {
        public delegate int TakesAWhileDelegate(int data,int ms);
        static void Main(string[] args)
        {
            TakesAWhileDelegate d1 = TakesAWhile;
            d1.BeginInvoke(1, 3000, TakesAWhileComplated, d1);
            for (int i = 0; i < 100; i++)
            {
                Console.Write(".");
                Thread.Sleep(50);
            }
            Console.ReadKey();
        }

        static int TakesAWhile(int data, int ms)
        {
            Console.WriteLine("TakesAWhile,start");
            Thread.Sleep(ms);
            Console.WriteLine("\nTakesAWhile complated");
            return ++data;
        }

        public static void TakesAWhileComplated (IAsyncResult ar)
        {
            if (ar == null) throw new ArgumentNullException("ar");
            TakesAWhileDelegate d1 = ar.AsyncState as TakesAWhileDelegate;
            Trace.Assert(d1 != null, "Invalid object type");

            int result = d1.EndInvoke(ar);
            Console.WriteLine("result:{0}", result);
            Console.ReadKey();
        }
    }
复制代码

 运行结果:

.TakesAWhile,start
................................................
TakesAWhile complated
result:2
...................................................

 

TakesAWhileComplated方法用AsyncCallback委托指定的参数和返回类型来定义 。 用BeginInvoke方法传递的最后一个参数可以使用ar.AsyncState读取。在TakesAWhileDelegate委托中,可以调用EndInvoke方法来获得结果。

注意:使用回调方法,必须注意这个方法从委托的线程中调用,而不是从主线程中调用。

编程模型和所有这些包含异步委托的选项--投票、等待句柄和异步回调--不仅能用于委托。相同的编程模型(即异步模式)在.NET Framework的各个地方都能见到。

例如,可以用HttpWebReques类的BeginGetResponse()方法异步发送HTTP Web请求,使用SqlComand类的BeginExecuteReader()方法给数据库发送异步请求。

这些参数类似于委托的BeginInvoke()方法的参数,也可以使用相同的方式获得结果。

posted on 2018-10-15 20:21  asdyzh  阅读(251)  评论(0编辑  收藏  举报

导航