Ajax实时显示股票信息实例中的问题

    本实例的代码请看上篇博客《AJAX实例之股票实时信息显示》。虽然Java和C#两门语言语法非常相似,但是细节上还是有很多不同之处,所以在转换的过程中,还是有几个问题:

  1. Java下有HttpServlet,C#下的一般处理程序
  2. Java下有HashMap,C#下的Dictionary
  3. Java下有Random类有nextBoolean(),C#灵活使用nextDouble()
  4. Java下有Timer使用匿名函数,C#使用委托

    不同

    一般处理程序    

    HttpServlet专门用于响应请求的类,最开始我用的是Asp.net下的Web窗体,但Web窗体很明显更倾向于可视,而这个例子所要求的服务端不必有页面,所以使用的是一般处理程序(*.ashx),这个和HttpServlet非常类似,可以专门用于处理简单的请求,相对于Web窗体更省资源且响应速度更快。

        Dictionary    

    C#没有HashMap,不过可以使用其Dictionary达到同样的效果,Dictionary存放的同样是键值对组合,当然值可以为对象类型。

    NextBoolean()

    Java下可以根据nextBoolean()决定是涨是降。

        // 新建一个生成随机数的对象
        final Random random = new Random();
	//上涨或下降
	if (random.nextBoolean()) {
		sz = 0 - sz;
	}
    C#呢?这可以灵活使用nextDouble(),nextDouble()取值为0~1,与0.5比较同样可以决定是涨还是降。

        Random rdm = new Random();
        //上涨浮动
        if (rdm.NextDouble() > 0.5)
        {
            sz = 0 - sz; 
        }

    匿名函数

    好吧,前三个问题很简单,第四个就比较困难了,先看一下未解决以前的计时代码(服务端部分代码):

  /// <summary>
    /// 初始化配置数据
    /// </summary>
    public  void InitNew()
    {
        
        //设定股票字典
        stock = new Dictionary<string, Stock>();
         stock.Add("300001", szzs);
         stock.Add("600000", pfyh);
         stock.Add("601398", gsyh);
         stock.Add("601857", zgsy);
        //设置计时器参数
        timer = new System.Timers. Timer();
        timer.Enabled = true;
        timer.Interval = 50;
        //执行计时器函数theout
        timer.Elapsed  +=new System.Timers.ElapsedEventHandler(theout);
          
    }
    /// <summary>
    /// 计时器执行函数
    /// </summary>
    /// <param name="source">事件源</param>
    /// <param name="e">事件参数</param>
    public void theout( object source,System.Timers.ElapsedEventArgs e)
    {
        //股票变动范围
        Random rdm = new Random();
        double rdm2 = rdm.NextDouble();
        //上涨浮动
        double sz = rdm2 * 30;
        double pf = rdm2 * 0.5;
        double gs = rdm2 * 0.1;
        double zg = rdm2 * 0.3;
        //下跌浮动

        if (rdm2 > 0.5)
        {
            sz = 0 - sz; 
        }
        if (rdm2 > 0.5)
        {
            pf = 0 - pf;
        }
        if (rdm2 > 0.5)
        {
            gs = 0 - gs;
        }
        if (rdm2 > 0.5)
        {
            zg = 0 - zg;
        }
        //当前股票价格
        szzs.SetCurrent(Math.Round((szzs.GetCurrent() + sz) * 100) / 100.0);
        pfyh.SetCurrent(Math.Round((pfyh.GetCurrent() + pf) * 100) / 100.0);
        gsyh.SetCurrent(Math.Round((gsyh.GetCurrent() + gs) * 100) / 100.0);
        zgsy.SetCurrent(Math.Round((zgsy.GetCurrent() + zg) * 100) / 100.0);
    }  
    没有加客户端代码,直接运行服务端代码,运行结果是:

    这是我们比较常用的委托方式,但是很明显,股票浮动值属性"ran"读取不出来,如果你把代码放到VS中逐过程调试会发现:程序会在theout事件中随机的重复执行。

    更改后的代码为:

    /// <summary>
    /// 初始化配置数据
    /// </summary>
    private void Init()
    {
        //新建四支股票
        Stock szzs = new Stock("300001", "上证指数", 300);
        Stock pfyh = new Stock("600000", "浦发银行", 25);
        Stock gsyh = new Stock("601398", "工商银行", 6.5);
        Stock zgsy = new Stock("601857", "中国石油", 19.1);
        //设定股票字典
        stock = new Dictionary<string, Stock>();
        //添加股票
        stock.Add("300001", szzs);
        stock.Add("600000", pfyh);
        stock.Add("601398", gsyh);
        stock.Add("601857", zgsy);
        //设置计时器参数,不要太大
        timer = new System.Timers.Timer(50);
        timer.Enabled = true;
        //执行计时器函数theout
       Random rdm = new Random();
        //每次只去一个,防止循环执行获取随机数
       double mdr = rdm.NextDouble();
        //timer的振荡事件,采用匿名函数方式执行
        timer.Elapsed += delegate(object source, System.Timers.ElapsedEventArgs e)
        {
            //股票变动范围
            //上涨浮动
            double sz = mdr * 30;
            double pf = mdr * 0.5;
            double gs = mdr * 0.1;
            double zg = mdr * 0.3;
            //下跌浮动
            if (mdr > 0.5)
            {
                sz = 0 - sz;
            }
            if (mdr > 0.5)
            {
                pf = 0 - pf;
            }
            if (mdr > 0.5)
            {
                gs = 0 - gs;
            }
            if (mdr > 0.5)
            {
                zg = 0 - zg;
            }
            //当前股票价格
            szzs.SetCurrent(Math.Round((szzs.GetCurrent() + sz) * 100) / 100.0);
            pfyh.SetCurrent(Math.Round((pfyh.GetCurrent() + pf) * 100) / 100.0);
            gsyh.SetCurrent(Math.Round((gsyh.GetCurrent() + gs) * 100) / 100.0);
            zgsy.SetCurrent(Math.Round((zgsy.GetCurrent() + zg) * 100) / 100.0);
        };
       
    }

    运行结果为:

    可以看到这次就能读取到股票浮动字段"ran"了,在VS中逐过程调试也会发现,每次计时器的振荡事件代码只执行一次。

    比较一下这两段代码的不同,差别仅是在计时器振荡事件代码的位置:第一段的时钟事件代码放到了theout事件中,而第二段代码则放到了匿名函数中,看似差别不大,但是这里涉及到了变量的作用域问题,第一段代码中,如果想使用

Stock szzs = new Stock("300001", "上证指数", 300);
    Stock pfyh = new Stock("600000", "浦发银行", 25);
    Stock gsyh = new Stock("601398", "工商银行", 6.5);
    Stock zgsy = new Stock("601857", "中国石油", 19.1);
这个变量,只能将其放到函数或事件外,用作全局变量;且
Random rdm = new Random();
        double rdm2 = rdm.NextDouble();
这两行代码放到theout中和匿名函数中也会有不同的运行结果。

        重复执行

        上面说到重复执行的问题,甚至会在

    /// <summary>
    /// 计时器执行函数
    /// </summary>
    /// <param name="source">事件源</param>
    /// <param name="e">事件参数</param>
    public void theout( object source,System.Timers.ElapsedEventArgs e)
    {
        //股票变动范围
        Random rdm = new Random();
        double rdm2 = rdm.NextDouble();
        //上涨浮动
        double sz = rdm2 * 30;
        double pf = rdm2 * 0.5;
        double gs = rdm2 * 0.1;
        double zg = rdm2 * 0.3;
}
        这几行代码之间无规律跳动执行,这个问题并没有解决,但是因为使用了匿名函数的方法,所以在整体功能实现上并没有问题,如果您知道问题所在,欢迎指教,问题代码下载地址: http://download.csdn.net/detail/lidaasky/4936350

    




评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值