zoukankan      html  css  js  c++  java
  • Silverlight+WCF 实战网络象棋最终篇之解决重复的消息提示(八)

    前言:

    最近有网友经常会问,在跟着做象棋对战的通讯中,在重复退出进入的时候,消息会重复出现,本节就这问题进行解说与优化。

    一:分析问题产生的原因?

     

    1:首先看App.xaml,里面定义了一个全局客户端回调:

    public static GameService.ServiceClient client;//回调的客户端

    并且这个回调我们全局只实例化一次,并且默认加载时定位到登陆页面:

    private void Application_Startup(object sender, StartupEventArgs e)
    {
       
    this.RootVisual = root;
       root.Children.Add(
    new Login());//默认定位到登录页面。
    }

    2:再看登录页面Login.xaml里,构造函数的初始化:

    public Login()
    {
                InitializeComponent();
                App.client.LoginCompleted 
    += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_LoginCompleted);
                Load();
    }

    我们对App.client.LoginCompleted初始化了一次事件,这时一切是正常的,接着我们进入房间,之后,我们返回系统回到登陆。

    3:接着看退出系统的按钮是怎么返回到登陆页面的:

            //退出系统
            private void btnLogout_Click(object sender, RoutedEventArgs e)
            {
                
    if (App.chess.IsGaming)
                {
                    btnGameLose_Click(
    nullnull);//发送认输
                    App.chess.IsGaming = false;
                }
                App.client.OutRoomAsync(App.player, App.player.RoomID, App.player.AttachInfo);
                ((App)Application.Current).RedirectTo(
    new Login());
            }

    看最后一行,我们又New Login了,这种情况,刚才第二步中的:App.client.LoginCompleted事件将被重复注册,因此,重复的事件注册引发了重复的消息提示。

    问题总结说明:

    对于消息的重复提示,基本都属于事件的重复注册造成的,我们之前的代码很多转向都使用new 控件()的方式在各个页面切换时,于是容易产生这种问题。

    二:解决消息重复问题

     

    从第一步中,我们分析到问题产生的根源,于是,我们可以想出很多方式,来解决这种问题,这里我介绍两种方式:

     

    先来看一下错误任法:注册事件前加先减,再加,示例代码如下:

    App.client.LoginCompleted -= new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_LoginCompleted);
    App.client.LoginCompleted 
    += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_LoginCompleted);

    网上有人说:每次注册前先去掉一下,然后再增加,逻辑上看起来好像没问题,刚自己试了下,纯忽悠型。

    现在介绍下我想到的两种方式:

    1:定义全局变量List<事件名称>,保存注册过的事件名称

    逻辑:在每次事件产生前,先判断一下事件是否存在,不存在则添加,存在则跳过,此方法实现简单,大伙一说就应该会了,所以直接跳过了。

    2:定义全局变量保存所有房间,于是在RedirectTo切换房间的时候,避免使用New 控件() 来避免再次执行事件注册事件

    下面进行代码整改:

    A:App.xaml全局定义每个房间的变量,并改造成属性,所幸控件就几个,定义也费不了多少力,代码如下:

            private static Login loginObj;
            
    public static Login LoginObj
            {
                
    get
                {
                    
    if (loginObj == null)
                    {
                        loginObj 
    = new Login();
                    }
                    
    //loginObj.Reset();
                    return loginObj;
                }
            }
            
    private static Room roomObj;
            
    public static Room RoomObj
            {
                
    get
                {
                    
    if (roomObj == null)
                    {
                        roomObj 
    = new Room();
                    }
                    
    //roomObj.Reset();
                    return roomObj;
                }
            }
            
    private static Index indexObj;
            
    public static Index IndexObj
            {
                
    get
                {
                    
    if (indexObj == null)
                    {
                        indexObj 
    = new Index();
                    }
                    
    //indexObj.Reset();
                    return indexObj;
                }
            }

    说明:

    这里有两点:1是改造属性方式,这样在调用时不用再写判断语句,2是注册的Reset()方法,后面会开启到。

    B:查找调用RedirectTo切换界面的代码,替换为:App.xxxxObj

    随便找个RedirectTo,右键查找所有引用,看看有几个要修改的地方,所幸也不多,如下图:

    说明:

    按上面的查找出来的代码,一个一个更改即可,如把new Index()换成App.IndexObj。

    OK,消息提示重复的问题,至此,是解决了,但是,将产生一点副作用,就是切回去的时候,状态需要重置。

     

    简单的示例说明就是:

    点登陆时,把按钮设置为不可用,然后你进去,再退出,看到的是“不可用”的按钮就没法再进去了。

    OK,状态重置的问题,就留到下节解决了。

    本节没关联啥好看图片,就随便挂一张在下面让大伙欣赏了:

    最后:谢谢大家对本系列的喜欢,谢谢支持~

    同时欢迎大家多到 秋色园 走走~~~

    PS:传说点一下推荐会有10个园豆的规则已经取消了,不过,喜欢的还是可以点一下“推荐”,thank you very much!!

  • 相关阅读:
    SiteMap 提交,并使用正确的方式提交给搜索引擎
    爱自己的人脸上散发的光芒是骗不了别人的,你会活在平静淡定喜悦中,绝少埋怨,鲜有不满,没有太多话需要澄清,说清楚,内心是一片宁静而有力量的海。
    PHP 调用webService方式
    Oracle数据库操作知道
    气泡 弹出 bootstrap-popover的配置与灵活应用
    mysql向表中某字段后追加一段字符串:
    LINUX 下安装一些东西,PHP Apach SSL 等
    在同一个页面上要使用多个百度分享,控件人分享的内容信息
    Linux study
    Mysql 备份
  • 原文地址:https://www.cnblogs.com/cyq1162/p/1926344.html
Copyright © 2011-2022 走看看