[PR]
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
プログラミング、3DCGとその他いろいろについて
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
先日WPFとWCFで遊んでいたらこれにはまったのでメモしておきます。
WCFのサーバーをコンソールアプリケーションで作り、クライアントをWPFで作っていたのですが、クライアントからサービスオブジェクトのメソッドを呼ぶと固まって、System.TimeoutExceptionがスローされてしまうのです(WCFでは、デフォルトで1分以内に向こう側から呼ばれたメソッドの処理が終わらないとTimeoutExceptionがスローされます)。
実のところこの原因は難しいことではなく、WCFのコールバックオブジェクトのイベント内(UIとは別スレッド)でWPFのButton.Contentを直接変更しようとしたために起きた問題で、Button.Dispatcher.BeginInvokeメソッドで簡単に解決する問題でした。
そうですそうです確かこれはWindows.Formsでも同じことをやった記憶があります。全く進歩がありません。こんなことをブログに書くのは恥ずかしいのですが、ある程度の範囲内なら、より痛い目にあえばより記憶が強力になるような気がしなくもないですからね。
コード
サーバー側のコードには問題がなかったのでクライアント側のコードだけを書きます(恥さらしは少ない方がいい!!)。
が、その前にどんな事をしようとしていたのかを簡単に説明しておきましょう。作ろうとしていたのは簡単なゲームで、プレイヤーは2人、それぞれのプレイヤーには最初に20点のライフと自分自身のウィンドウが与えられ、プレイヤーは自分のウィンドウのボタンを押すことで相手のライフを3減らすことができます。自分のライフが0になったら負けなので、ボタンをなるべく連打して相手のライフを早く0にしようとします。遊ぶ時にはそれぞれのプレイヤーは別々のパソコンを使うことになるのでしょう(そのためのWCFです)。そして、ボタンのクリックの速さを競うわけです。
ゲームとしては全然面白くない気がしますが、WCFの練習ならこういうのもいいんじゃないのかなぁと言い訳をしておきます。WPFとWCFに慣れたらもうちょっとフクザツにできるはずですからね。もしかしたらMagic : The Gatheringみたいにできるかもしれません。
で、問題のコードですが、これでした:
player.LifeChanged += delegate { this.YourLifeButton.Content = player.GetLife(); };
player.LifeChanged += delegate
{
YourLifeButton.Dispatcher.BeginInvoke(
System.Windows.Threading.DispatcherPriority.Background,
(System.Action)delegate
{
YourLifeButton.Content = player.GetLife();
}
);
};