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(
null null ); // 发送认输
                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!!

版权声明:本文原创发表于博客园,作者为路过秋天,原文链接:

http://www.cnblogs.com/cyq1162/archive/2011/01/05/1926344.html

目录
打赏
0
0
0
0
52
分享
相关文章
目标检测实战(一):CIFAR10结合神经网络加载、训练、测试完整步骤
这篇文章介绍了如何使用PyTorch框架,结合CIFAR-10数据集,通过定义神经网络、损失函数和优化器,进行模型的训练和测试。
340 2
目标检测实战(一):CIFAR10结合神经网络加载、训练、测试完整步骤
Python网络爬虫:Scrapy框架的实战应用与技巧分享
【10月更文挑战第27天】本文介绍了Python网络爬虫Scrapy框架的实战应用与技巧。首先讲解了如何创建Scrapy项目、定义爬虫、处理JSON响应、设置User-Agent和代理,以及存储爬取的数据。通过具体示例,帮助读者掌握Scrapy的核心功能和使用方法,提升数据采集效率。
274 6
HarmonyOS NEXT 实战系列10-网络通信
本文介绍了网络通信相关知识,包括HTTP协议的工作原理、鸿蒙系统中HTTP模块的使用方法、Promise异步操作处理机制及async/await语法糖的应用,以及JSON数据格式的语法规则与转换方法。重点讲解了HTTP请求响应流程、鸿蒙开发中的网络权限申请与代码实现、Promise三种状态及创建方式,并通过示例说明异步编程技巧和JSON在数据传递中的应用。
71 10
Hyper V上网实战:多虚拟机网络环境配置
在Hyper-V环境中配置多虚拟机网络以实现上网功能,需完成以下步骤:1. 确认Hyper-V安装与物理网络连接正常;2. 配置虚拟交换机(外部、内部或专用)以支持不同网络需求;3. 设置虚拟机网络适配器并关联对应虚拟交换机;4. 验证虚拟机网络连接状态;5. 根据场景需求优化多虚拟机网络环境。此外,还需注意网络隔离、性能监控及数据备份等事项,确保网络安全稳定运行。
Python 高级编程与实战:深入理解网络编程与异步IO
在前几篇文章中,我们探讨了 Python 的基础语法、面向对象编程、函数式编程、元编程、性能优化、调试技巧、数据科学、机器学习、Web 开发和 API 设计。本文将深入探讨 Python 在网络编程和异步IO中的应用,并通过实战项目帮助你掌握这些技术。
YOLO11实战:新颖的多尺度卷积注意力(MSCA)加在网络不同位置的涨点情况 | 创新点如何在自己数据集上高效涨点,解决不涨点掉点等问题
本文探讨了创新点在自定义数据集上表现不稳定的问题,分析了不同数据集和网络位置对创新效果的影响。通过在YOLO11的不同位置引入MSCAAttention模块,展示了三种不同的改进方案及其效果。实验结果显示,改进方案在mAP50指标上分别提升了至0.788、0.792和0.775。建议多尝试不同配置,找到最适合特定数据集的解决方案。
1657 0
Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
本文介绍了Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
423 7
网络安全的盾与剑:漏洞防御与加密技术的实战应用
在数字化浪潮中,网络安全成为保护信息资产的重中之重。本文将深入探讨网络安全的两个关键领域——安全漏洞的防御策略和加密技术的应用,通过具体案例分析常见的安全威胁,并提供实用的防护措施。同时,我们将展示如何利用Python编程语言实现简单的加密算法,增强读者的安全意识和技术能力。文章旨在为非专业读者提供一扇了解网络安全复杂世界的窗口,以及为专业人士提供可立即投入使用的技术参考。
网络空间安全之一个WH的超前沿全栈技术深入学习之路(9):WireShark 简介和抓包原理及实战过程一条龙全线分析——就怕你学成黑客啦!
实战:WireShark 抓包及快速定位数据包技巧、使用 WireShark 对常用协议抓包并分析原理 、WireShark 抓包解决服务器被黑上不了网等具体操作详解步骤;精典图示举例说明、注意点及常见报错问题所对应的解决方法IKUN和I原们你这要是学不会我直接退出江湖;好吧!!!
网络空间安全之一个WH的超前沿全栈技术深入学习之路(9):WireShark 简介和抓包原理及实战过程一条龙全线分析——就怕你学成黑客啦!
网络空间安全之一个WH的超前沿全栈技术深入学习之路(8-2):scapy 定制 ARP 协议 、使用 nmap 进行僵尸扫描-实战演练、就怕你学成黑客啦!
scapy 定制 ARP 协议 、使用 nmap 进行僵尸扫描-实战演练等具体操作详解步骤;精典图示举例说明、注意点及常见报错问题所对应的解决方法IKUN和I原们你这要是学不会我直接退出江湖;好吧!!!
网络空间安全之一个WH的超前沿全栈技术深入学习之路(8-2):scapy 定制 ARP 协议 、使用 nmap 进行僵尸扫描-实战演练、就怕你学成黑客啦!

热门文章

最新文章

下一篇
oss创建bucket
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等