欢迎您来到GIS动力

加入收藏 免费注册 用户登陆 帮助中心
首页 新闻动态 技术专栏 银杏树下 学习考研 软件下载 求职招聘 许愿瓶 节日祝福 用户中心 精彩推荐 资源搜索 地图
专栏导航: AO开发 | SO开发 | ArcGIS桌面 | 超图桌面 | 开发语言 | 数据库 | WebGIS | 银杏文学 | 研究生考题 | FreeMap FreeTalk
   您现在位于: 首页技术专栏开发语言 → 正文
异步调用结果的获取
08-09-03 10:22:15 作者:天方 出处:http://www.cnblogs.com/TianFang

很多时候,为了获得更好的响应速度和并发性时,我们采用主动对象(线程池)的模式来实现对函数的执行。

这样做一个不便之处在于:函数调用者并不是函数的执行者,调用者并不知道何时函数执行完成。特别是有的时候,函数的调用者需要根据函数的返回值来决定下一步的操作,这个时候就需要一种机制来获取函数的返回值。

关于异步调用及返回值的获取,C#本身的委托异步调用是一种非常完善的异步机制。然而有时不能适合如我们的需要,这里从底层开始简单的实现自己的异步机制,可以有一个更清楚的认识和学习,并且和C#提供的语法糖无关,可以移植到各种其它语言中去。

异步调用的返回值的获取方式有两种:同步获取和异步获取。

异步获取:

异步获取非常简单,函数调用者在对执行者添加函数任务时,同时注册一个回调函数。函数执行者执行玩函数后,执行回调函数,返回值通过回调函数的参数带回。

同步获取:

异步获取的方式获取的返回值是在执行者的线程返回,而不是在调用者的线程中,使用起来不是很方便,同步调用则可以解决这个问题

同步调用主要分为以下几个步骤。

  1. 函数调用者添加函数执行任务后,阻塞当前线程。
  2. 函数执行者执行完函数后,将返回值放在和调用者约定的位置,并通知函数调用者线程。
  3. 函数调用者接收到通知后,停止阻塞线程,通过约定的位置获取返回值,继续执行。

PS:其实通过这种方式从效率上和复杂性来讲,不如直接调用函数来得方便。这种方式一般在如下几种情况下使用:

  1. 函数只能通过异步方式执行,而为了程序逻辑简单,需要用同步方式获取。
  2. 函数调用虽然非常耗时,但只在很少的情况下需要用同步的方式获取返回值,这时使用异步调用仍能节省许多时间。

两种获取返回值方式的比较:

  • 同步获取逻辑上比较简单。
  • 异步获取效率较高。

每种方式的优点是对方的缺电,两种方式互为补充,可根据具体情况适当使用,甚至一起使用,

实现:

异步调用的实现非常简单,特别是在C#支持lamabda表达式之后,可以以一种非常优雅的方式封装函数,获取返回值,这里就不介绍了。

同步调用的一种简单的实现如下:

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

using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Future<string> f = new Future<string>(Foo);
            ThreadPool.QueueUserWorkItem(x => { Thread.Sleep(3 * 1000); f.Excute(); });
            //ThreadPool.QueueUserWorkItem(x => f.Excute());

            Thread.Sleep(1000);
            Console.WriteLine("waitting answer...");

            //f.Wait();
            //Console.WriteLine("answer:\t" + f.Value);

            if (f.Wait(TimeSpan.FromSeconds(5)))
                Console.WriteLine("answer:\t" + f.Value);
            else
                Console.WriteLine("time out");

            Console.WriteLine("test finished");
            Thread.Sleep(-1);
        }

        static string Foo()
        {
            Console.WriteLine("foo begin");
            string s = Console.ReadLine();
            Console.WriteLine("foo finished.");
            return s;
        }
    }

    delegate T ExcuteHanlder<T>();

    class Future<T>
    {
        public T Value { get; private set; }
        public bool Ready { get; private set; }

        ExcuteHanlder<T> function;
        public Future(ExcuteHanlder<T> function)
        {
            this.function = function;
        }

        public void Excute()
        {
            Value = function();

            lock (this)
            {
                Ready = true;
                Monitor.Pulse(this);
            }
        }

        public bool Wait()
        {
            return Wait(TimeSpan.Zero);
        }

        public bool Wait(TimeSpan timeout)
        {
            lock (this)
            {

                if (!Ready)
                {
                    if (timeout == TimeSpan.Zero)
                        return Monitor.Wait(this);
                    else
                        return Monitor.Wait(this, timeout);
                }
            }
            return true;
        }

    }
}


(本文已被浏览 次)
发布人:admin
推荐给好友:发送给好友
上篇新闻:
下篇新闻:
相关评论
发表我的评论
  • 尊重网上道德,遵守《全国人大常委会关于维护互联网安全的决定》及中华人民共和国其他各项有关法律法;
  • 本站有权保留或删除您发表的任何评论内容;
  •   相关文章  
    无相关新闻

    关于我们友情链接 ┋ 与我在线 ┋ 管理 ┋ TOP
     
    网站当前版本:GisPower CMS V3.0
    『GIS 动力』- http://www.gispower.org/
    联系我们:webmaster#gispower.org
    Copyright (c) 2003-2007 GisPOwer.Org. All Rights Reserved.
     

                   滇ICP备05006901号