• <code id="58gs9"></code>

      <mark id="58gs9"></mark>
      1. 当前位置:首页 > 开发教程 > WCF技术 >

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

        时间:2014-05-20 16:40 来源: 作者: 浏览: 收藏 挑错 推荐 打印

        前言:

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

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

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

         

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

         

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

         

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

         

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

        线程阻塞?怎么理解?

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

         

        会产生什?#27425;?#39064;?

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

         

        解决方案?

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

         

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

         

        b:更优的解决方案

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

         

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

         

        1:?#32431;?#32431;?#20540;?#38271;成什么样

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

         

        结果所见如图:

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

        ?#24471;鰨?/p>

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

         

        2:改造-界面小小改动

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

        Silverlight+WCF 实战-网络象棋最终篇之非线程阻塞倒计时窗口(四
        <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>

         

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

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

         

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

        a:加入计时器并初始化

        Silverlight+WCF 实战-网络象棋最终篇之非线程阻塞倒计时窗口(四
               DispatcherTimer timer;//定时器
                public MsgBox()
                {
                    InitializeComponent();
                    timer 
        = new DispatcherTimer();
                    timer.Interval 
        = TimeSpan.FromSeconds(1);
                    timer.Tick 
        += new EventHandler(timer_Tick);
                }

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

        Silverlight+WCF 实战-网络象棋最终篇之非线程阻塞倒计时窗口(四
               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","路过秋天");

        如图:

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

         

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

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

         

        于是,要实现了:

        a:如何实现回调?

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

        Silverlight+WCF 实战-网络象棋最终篇之非线程阻塞倒计时窗口(四
                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();
        //调用一下关闭
                }

         

        问题?我们难道?#36816;?#26377;的确定都执行相同的代码?

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

         

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

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

         

        匿名委托实现:

        Action<bool> callBackEvent;//全局定义

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

         

        那委托是如何传入?#27169;縎how方法增加扩展参数传入。

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

        Silverlight+WCF 实战-网络象棋最终篇之非线程阻塞倒计时窗口(四完整的MsgBox代码
            public partial class MsgBox : ChildWindow
            {
                
        int defaultTime = 3;//默认N秒
                string userTitle;
                DispatcherTimer timer;
        //定时器
                Action<bool> callBackEvent;
                
        bool autoOKConfirm = true;
                
        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)
                {
                    
        //待实现
                }
                
        void timer_Tick(object sender, EventArgs e)
                {
                    Title 
        = string.Format(userTitle + " [倒计时自动确定:{0}秒]", defaultTime);
                    defaultTime
        --;
                    
        if (defaultTime == 0)
                    {
                        ResetTimer();
                        
        if (autoOKConfirm)
                        {
                            OKButton_Click(
        nullnull);
                        }
                        
        else
                        {
                            CancelButton_Click(
        nullnull);
                        }
                    }
                }
                
        void ResetTimer()
                {
                    timer.Stop();
                    defaultTime 
        = 3;
                }
                
        public void Show(string msg, string title)
                {
                    Show(msg, title, defaultTime, 
        nulltrue, MessageBoxButton.OK);
                }
                
        public void Show(string msg, string title, int timeSecond, Action<bool> callBack)
                {
                    Show(msg, title, timeSecond, callBack, 
        false, MessageBoxButton.OKCancel);
                }
                
        public void Show(string msg, string title, int timeSecond, Action<bool> callBack, bool autoOK, MessageBoxButton button)
                {
                    tbMsg.Text 
        = msg;
                    userTitle 
        = title;
                    
        if (button == MessageBoxButton.OK)
                    {
                        OKButton.Content 
        = "确定";
                        CancelButton.Visibility 
        = System.Windows.Visibility.Collapsed;
                    }
                    
        else
                    {
                        CancelButton.Visibility 
        = System.Windows.Visibility.Visible;
                        OKButton.Content 
        = "同意";
                        CancelButton.Content 
        = "拒绝";
                    }
                    defaultTime 
        = timeSecond;
                    autoOKConfirm 
        = autoOK;
                    callBackEvent 
        = callBack;
                    Show();
                    timer.Start();
                }
                
        private void OKButton_Click(object sender, RoutedEventArgs e)
                {
                    
        this.DialogResult = true;
                }

                
        private void CancelButton_Click(object sender, RoutedEventArgs e)
                {
                    
        this.DialogResult = false;
                }
            }

         

         

        三:接下来便是苦力活了,?#35328;?#26469;用到传统对框的提示,通通改过来。

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

         

        最后上一实?#35270;?#29992;中的图:

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

        Silverlight+WCF 实战-网络象棋最终篇之非线程阻塞倒计时窗口(四转载<\/script>');

        WCF技术阅读排行

        最新文章

        大富翁棋牌娱乐官网

      2. <code id="58gs9"></code>

          <mark id="58gs9"></mark>

          1. <code id="58gs9"></code>

              <mark id="58gs9"></mark>
              1. 湖南快乐十分同尾走势图 7星彩杀号定胆 彩票合买选号全 北京快三一定牛走势图l 刘伯温四肖中特期期免费公开 云南十一选五遗漏 彩之网 快乐十分八个号多少钱 青海快三中奖规则 黑龙江时时彩出号 大乐透走势图浙江风采2 河北20选5过滤软件 云南时时彩交流群 好运彩3d之家 大乐透开奖直播在哪看