日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

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

發布時間:2025/3/21 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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代碼 ????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(
null,?null);
????????????????}
????????????????
else
????????????????{
????????????????????CancelButton_Click(
null,?null);
????????????????}
????????????}
????????}
????????
void?ResetTimer()
????????{
????????????timer.Stop();
????????????defaultTime?
=?3;
????????}
????????
public?void?Show(string?msg,?string?title)
????????{
????????????Show(msg,?title,?defaultTime,?
null,?true,?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;
????????}
????}

?

?

三:接下來便是苦力活了,把原來用到傳統對框的提示,通通改過來。

這個改的點有點多,留到下節MsgBox使用時細細說了。

?

最后上一實際應用中的圖:

轉載于:https://www.cnblogs.com/cyq1162/archive/2010/10/27/1861281.html

總結

以上是生活随笔為你收集整理的Silverlight+WCF 实战-网络象棋最终篇之非线程阻塞倒计时窗口(四)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。