IAsyncResult 操作结果分析

对于访问异步操作的结果,应用程序开发人员有若干种设计选择。正确的选择取决于应用程序是否有可以在操作完成时执行的指令。如果应用程序在接收到异步操作结果之前不能进行任何其他工作,则必须先阻止该应用程序进行其他工作,等到获得这些操作结果后再继续进行。若要在异步操作完成之前阻止应用程序,您可以使用下列方法之一:

  • 从应用程序的主线程调用 EndOperationName,阻止应用程序执行,直到操作完成之后再继续执行

    使用 Dns 类中的异步方法来检索用户指定的计算机的域名系统信息

    IAsyncResult result = Dns.BeginGetHostEntry("127.0.0.1",null,null);
                Console.WriteLine("Processing your request for information...");
                try
                {
                    IPHostEntry host = Dns.EndGetHostEntry(result);
                    string[] aliases = host.Aliases;
                    IPAddress[] address = host.AddressList;
                    if (aliases.Length>0)
                    {
                        Console.WriteLine("Aliases");
                        for (int i = 0; i < aliases.Length; i++)
                        {
                            Console.WriteLine(" {0} ",aliases[i]);
                        }
                    }
                    if (address.Length>0)
                    {
                        Console.WriteLine("Addresses");
                        for (int i = 0; i < address.Length; i++)
                        {
                            Console.WriteLine(" {0} ",address[i].ToString());
                        }
                    }
                }
                catch (SocketException ex)
                {
                    Console.WriteLine("An exception occurred while processing the request: {0}",ex.Message);
                }


  • 使用 AsyncWaitHandle 来阻止应用程序执行,直到一个或多个操作完成之后再继续执行。

    那些在异步操作完成前一直使用一个或多个 WaitHandle 对象阻止其他操作的应用程序通常会调用 BeginOperationName 方法,执行不需要等待操作结果的工作,然后一直等到异步操作完成才停止阻止。通过使用 AsyncWaitHandle 调用 WaitOne 方法之一,应用程序可以阻止一个操作。若要在等待一组异步操作完成期间阻止执行,应将相关的 AsyncWaitHandle 对象存储在数组中,然后调用 WaitAll 方法之一。若要在等待一组异步操作中的任一操作完成时阻止其他操作,应将关联的 AsyncWaitHandle 对象存储在数组中,然后调用 WaitAny 方法之一。

    IAsyncResult result = Dns.BeginGetHostEntry("127.0.0.1",null,null);
                Console.WriteLine("Processing request for information...");
                result.AsyncWaitHandle.WaitOne();   //使用与异步操作关联的 WaitHandle 来阻止
                try
                {
                    IPHostEntry host = Dns.EndGetHostEntry(result);
                    string[] aliases = host.Aliases;
                    IPAddress[] address = host.AddressList;
                    if (aliases.Length>0)
                    {
                        Console.WriteLine("Aliases");
                        for (int i = 0; i < aliases.Length; i++)
                        {
                            Console.WriteLine(" {0} ",aliases[i]);
                        }
                    }
                    if (address.Length>0)
                    {
                        Console.WriteLine("Addresses");
                        for (int i = 0; i < address.Length; i++)
                        {
                            Console.WriteLine(" {0} ",address[i].ToString());
                        }
                    }
                }
                catch (SocketException ex)
                {
                    Console.WriteLine("Exception occurred while processing the request: {0}",ex.Message);
                }


在异步操作完成时不需要阻止的应用程序可使用下列方法之一:

  • 按以下方式轮询操作完成状态:定期检查 IsCompleted 属性,操作完成后调用 EndOperationName

    private void button3_Click(object sender, EventArgs e)
            {
                IAsyncResult result = Dns.BeginGetHostEntry("127.0.0.1", null, null);
                Console.WriteLine("Processing request for information...");
                while (result.IsCompleted != true)    //开始异步操作,直到操作完成
                {
                    UpdateUserInterface();
                }
                try
                {
                    IPHostEntry host = Dns.EndGetHostEntry(result);
                    string[] aliases = host.Aliases;
                    IPAddress[] address = host.AddressList;
                    if (aliases.Length > 0)
                    {
                        Console.WriteLine("Aliases");
                        for (int i = 0; i < aliases.Length; i++)
                        {
                            Console.WriteLine(" {0} ", aliases[i]);
                        }
                    }
                    if (address.Length > 0)
                    {
                        Console.WriteLine("Addresses");
                        for (int i = 0; i < address.Length; i++)
                        {
                            Console.WriteLine(" {0} ", address[i].ToString());
                        }
                    }
                }
                catch (SocketException ex)
                {
                    Console.WriteLine("Exception occurred while processing the request: {0}", ex.Message);
                }
            }
    
    
            static void UpdateUserInterface()
            {
                Console.WriteLine("更新时间:"+DateTime.Now.ToString());
            }


  • 使用 AsyncCallback 委托来指定操作完成时要调用的方法。

    static int requestCounter;
            static ArrayList hostData = new ArrayList();
            static StringCollection hostNames = new StringCollection();
            static void UpdateUserInterfaceTwo()
            {
                Console.WriteLine("{0} requests remaining.更新时间:{1}",requestCounter,DateTime.Now.ToString());
            }
            static void ProcessDnsInformation(IAsyncResult result)
            {
                string hostName = (string)result.AsyncState;
                hostNames.Add(hostName);
                try
                {
                    IPHostEntry host = Dns.EndGetHostEntry(result);
                    hostData.Add(host);
                }
                catch (SocketException ex)
                {
                    hostData.Add(ex.Message);
                }
                finally
                {
                    Interlocked.Decrement(ref requestCounter);
                }
            }
    
    
            private void button4_Click(object sender, EventArgs e)
            {
                AsyncCallback callback = new AsyncCallback(ProcessDnsInformation);  //创建了引用 ProcessDnsInformation 方法的 AsyncCallback 委托
                string host = "127.0.0.1";
                Interlocked.Increment(ref requestCounter);
                Dns.BeginGetHostEntry(host,callback,host);
                while (requestCounter>0)
                {
                    UpdateUserInterfaceTwo();
                }
                for (int i = 0; i < hostNames.Count; i++)
                {
                    object data = hostData[i];
                    string message = data as string;
                    if (message!=null)
                    {
                        Console.WriteLine("Request for {0} returned message: {1}",hostNames[i],message);
                        continue;
                    }
                    IPHostEntry h = (IPHostEntry)data;
                    string[] aliases = h.Aliases;
                    IPAddress[] address = h.AddressList;
                    if (aliases.Length>0)
                    {
                        Console.WriteLine("Aliases for {0}",hostNames[i]);
                        for (int j = 0; j < aliases.Length; j++)
                        {
                            Console.WriteLine(" {0} ",aliases[j]);
                        }
                    }
                    if (address.Length>0)
                    {
                        Console.WriteLine("Addresses for {0}",hostNames[i]);
                        for (int k = 0; k < address.Length; k++)
                        {
                            Console.WriteLine(" {0} ",address[k].ToString());
                        }
                    }
                }
            }

    总结:以上查询IAsyncResult的方法都会阻塞当前进程,尤其是CS程序会出现无响应状态,如果需求是需要阻塞当前线程的可以用上面的方法,正在学习,期待有不阻塞的方法!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值