Silverlight+WCF 实战-网络象棋最终篇之非线程阻塞倒计时窗口(四)

简介:

前言:

在前面的系列中,我们虽然完成了其大部分功能,但是,离正真运行,还是有一大段距离

当你F5运行时,在弹出对话框之后,如果你不即时点确定,或者上个WC回来之后,你会发现已经提示出错了

这节开始,我们将对其进行一小步一小步的优化,来避免一些明显容易引发的错误。

 

感知一下最原始的消息弹出框如下图:

 

 

一:传统消息框,容易引发命案

 

1:原始的消息框,是线程阻塞类型的,很容易引发超时问题

线程阻塞?怎么理解?

简单的说就是,WCF服务端给客户端发送了消息提示之后,一直进入等待状态,直到玩家点了确定,这时才继续做其它事情。

 

会产生什么问题?

玩家上WC去了?消息没人确认,自然就会超时引发异常了,而且那线程也没法接下去干其它活。

 

解决方案?

a:传统解决方案[加上倒计时,还是线程阻塞类型]

 

当初我只是想在这传统的消息框上加上倒计时自动确认,这样可以少一点避免超时情况。
于是搜了一些资料,发现要用winapi来处理,这个这个....大才小用了吧。

 

b:更优的解决方案

无意中发现Silverlight的ChildWindow,正好解决了这一问题。
因为 ChildWindow使用异步方式,非线程阻塞,消息一弹之后线程就回家去了。
而且用Sivlerlight内置的定时器DispatcherTimer,非常容易实现倒计时。

 

二:实现自定义非线程阻塞倒计时对话框,纯种Sivlerlight

 

1:看看纯种的长成什么样

新建项目-》Silverlight 子窗口 -》起名叫MsgBox-》找另一个界面调用一下。
比如在登陆页面测试一下:MsgBox box=new MsgBox();box.Show();

 

结果所见如图:

说明:

1:有背景灰色层,界面原生的还传统消息框好看多了。
2:重点提示:当初刚试的时候是直接运行MsgBox,然后在其构造函数中调用Show(),结果是出不来的。

 

2:改造-界面小小改动

我们将原来的xaml改造成如下:

复制代码
< controls:ChildWindow  x:Class ="ChessProject.MsgBox"  ...省略一点...  Width ="290"  Height ="141"   Title ="系统消息" >
    
< Grid  x:Name ="LayoutRoot"  Margin ="2"  Height ="97"  Width ="270" >
        
< Button  Visibility ="Collapsed"  x:Name ="CancelButton"  Content ="取消"  Click ="CancelButton_Click"  Width ="75"  Height ="23"  HorizontalAlignment ="Right"  Margin ="0,62,93,12"   />
        
< Button  x:Name ="OKButton"  Content ="确定"  Click ="OKButton_Click"  Width ="75"  Height ="23"  HorizontalAlignment ="Right"  Margin ="0,62,10,12"   />
        
< TextBlock  Height ="41"  TextWrapping ="Wrap"  HorizontalAlignment ="Left"  Margin ="15,15,0,0"  Name ="tbMsg"  Text ="请按确定按钮确定"  VerticalAlignment ="Top"  Width ="224"   />
    
</ Grid >
</ controls:ChildWindow >
复制代码

 

界面效果如图,和上图差不多[这里把取消放在前面,只是为了不显示取消时,确定还保留在原位好看点]:

 

3:改造,在标题加入倒计时

a:加入计时器并初始化

复制代码
       DispatcherTimer timer; // 定时器
         public  MsgBox()
        {
            InitializeComponent();
            timer 
=   new  DispatcherTimer();
            timer.Interval 
=  TimeSpan.FromSeconds( 1 );
            timer.Tick 
+=   new  EventHandler(timer_Tick);
        }
复制代码

b:新加show方法并实现倒计时

复制代码
        int  defaultTime  =   3 ; // 默认N秒
         string  userTitle;
       DispatcherTimer timer;
// 定时器
         public  MsgBox()
        {
            
// ...省略...
        }
        
void  timer_Tick( object  sender, EventArgs e)
        {
            Title 
=   string .Format(userTitle  +   "  [倒计时自动确定:{0}秒] " , defaultTime);
            defaultTime
-- ;
            
if  (defaultTime  ==   0 )
            {
                ResetTimer();
            }
        }
        
void  ResetTimer()
        {
            timer.Stop();
            defaultTime 
=   3 ;
        }
        
public   void  Show( string  msg,  string  title)
        {
            tbMsg.Text 
=  msg;
            userTitle 
=  title;
            Show();
            timer.Start();
        }
复制代码

c:再调用一下看结果

MsgBox box  =   new  MsgBox();
box.Show(
" http://cyq1162.cnblogs.com " , " 路过秋天 " );

如图:

 

4:扩展show函数:加入回调/倒计时时间/按钮类型/默认确认类型

首先:这个子窗口是异步的,所以,在点击完确定时,需要增加多一个回调函数;
接着:默认3秒,很明显情况不同,时间也要稍为增加变动一下;
然后:有时候按钮只是确定,有时候就是取消+确定;
最后:倒计时时间到了,默认执行确定,还是执行取消。

 

于是,要实现了:

a:如何实现回调?

默认子窗口就有Closed事件,我们用它的事件,在点击确定或取消时,执行Close()方法

复制代码
         public  MsgBox()
        {
            InitializeComponent();
            timer 
=   new  DispatcherTimer();
            timer.Interval 
=  TimeSpan.FromSeconds( 1 );
            timer.Tick 
+=   new  EventHandler(timer_Tick);
            
this .Closed  +=   new  EventHandler(MsgBox_Closed);
        }
        
void  MsgBox_Closed( object  sender, EventArgs e)
        {
            
// 待实现
         }
        
private   void  OKButton_Click( object  sender, RoutedEventArgs e)
        {
            
this .DialogResult  =   true ;
            Close();
// 调用一下关闭
        }

        
private   void  CancelButton_Click( object  sender, RoutedEventArgs e)
        {
            
this .DialogResult  =   false ;
            Close();
// 调用一下关闭
        }
复制代码

 

问题?我们难道对所有的确定都执行相同的代码?

首先说:异步不能像同步那样写if(show(xxx,xxx)){方法}
于是说:这是个很严重的问题,因为不同的确定,我们执行的事件肯定是不同的。

 

解决问题?匿名委托出手了!!!

匿名委托:[Action < T1,T2,T3...N个重载 > ],这是个很好用的东东,可以传进方法名称,在执行后调用不同的方法。

 

匿名委托实现:

复制代码
Action < bool >  callBackEvent; // 全局定义

void  MsgBox_Closed( object  sender, EventArgs e)
{
    
if  (callBackEvent  !=   null )
    {
        callBackEvent(DialogResult.Value);
    }
}
复制代码

 

那委托是如何传入的?Show方法增加扩展参数传入。

b:这里贴出完整代码,一并实现:倒计时时间/按钮类型/默认确认类型

完整的MsgBox代码

 

 

三:接下来便是苦力活了,把原来用到传统对框的提示,通通改过来。

这个改的点有点多,留到下节MsgBox使用时细细说了。

 

最后上一实际应用中的图:

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

http://www.cnblogs.com/cyq1162/archive/2010/10/27/1861281.html

目录
打赏
0
0
0
0
52
分享
相关文章
🧠Android多线程与异步编程实战!告别卡顿,让应用响应如丝般顺滑!🧵
【7月更文挑战第28天】在Android开发中,确保UI流畅性至关重要。多线程与异步编程技术可将耗时操作移至后台,避免阻塞主线程。我们通常采用`Thread`类、`Handler`与`Looper`、`AsyncTask`及`ExecutorService`等进行多线程编程。
101 2
Java并发编程实战:使用synchronized关键字实现线程安全
Java并发编程实战:使用synchronized关键字实现线程安全
111 0
面试必问的多线程优化技巧与实战
多线程编程是现代软件开发中不可或缺的一部分,特别是在处理高并发场景和优化程序性能时。作为Java开发者,掌握多线程优化技巧不仅能够提升程序的执行效率,还能在面试中脱颖而出。本文将从多线程基础、线程与进程的区别、多线程的优势出发,深入探讨如何避免死锁与竞态条件、线程间的通信机制、线程池的使用优势、线程优化算法与数据结构的选择,以及硬件加速技术。通过多个Java示例,我们将揭示这些技术的底层原理与实现方法。
191 3
Java 多线程并发控制:深入理解与实战应用
《Java多线程并发控制:深入理解与实战应用》一书详细解析了Java多线程编程的核心概念、并发控制技术及其实战技巧,适合Java开发者深入学习和实践参考。
133 8
Java多线程编程中的并发容器:深入解析与实战应用####
在本文中,我们将探讨Java多线程编程中的一个核心话题——并发容器。不同于传统单一线程环境下的数据结构,并发容器专为多线程场景设计,确保数据访问的线程安全性和高效性。我们将从基础概念出发,逐步深入到`java.util.concurrent`包下的核心并发容器实现,如`ConcurrentHashMap`、`CopyOnWriteArrayList`以及`BlockingQueue`等,通过实例代码演示其使用方法,并分析它们背后的设计原理与适用场景。无论你是Java并发编程的初学者还是希望深化理解的开发者,本文都将为你提供有价值的见解与实践指导。 --- ####
探索Python的并发编程:线程与进程的实战应用
【10月更文挑战第4天】 本文深入探讨了Python中实现并发编程的两种主要方式——线程和进程,通过对比分析它们的特点、适用场景以及在实际编程中的应用,为读者提供清晰的指导。同时,文章还介绍了一些高级并发模型如协程,并给出了性能优化的建议。
83 3
|
6月前
|
Reactor实战,创建一个简单的单线程Reactor(理解了就相当于理解了多线程的Reactor)
本文通过一个简单的单线程Reactor模式的Java代码示例,展示了如何使用NIO创建一个服务端,处理客户端的连接和数据读写,帮助理解Reactor模式的核心原理。
80 0
Reactor实战,创建一个简单的单线程Reactor(理解了就相当于理解了多线程的Reactor)
|
7月前
|
领略Lock接口的风采,通过实战演练,让你迅速掌握这门高深武艺,成为Java多线程领域的武林盟主
领略Lock接口的风采,通过实战演练,让你迅速掌握这门高深武艺,成为Java多线程领域的武林盟主
64 7
🧠Android多线程与异步编程实战!告别卡顿,让应用响应如丝般顺滑!🧵
在Android开发中,为应对复杂应用场景和繁重计算任务,多线程与异步编程成为保证UI流畅性的关键。本文将介绍Android中的多线程基础,包括Thread、Handler、Looper、AsyncTask及ExecutorService等,并通过示例代码展示其实用性。AsyncTask适用于简单后台操作,而ExecutorService则能更好地管理复杂并发任务。合理运用这些技术,可显著提升应用性能和用户体验,避免内存泄漏和线程安全问题,确保UI更新顺畅。
220 5
异步&线程池 CompletableFuture 异步编排 实战应用 【终结篇】
这篇文章通过一个电商商品详情页的实战案例,展示了如何使用`CompletableFuture`进行异步编排,以解决在不同数据库表中查询商品信息的问题,并提供了详细的代码实现和遇到问题(如图片未显示)的解决方案。
异步&线程池 CompletableFuture 异步编排 实战应用 【终结篇】
AI助理

你好,我是AI助理

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