2014年4月16日水曜日

WPF での DoEvents

Windows Form の頃は、時間のかかる処理をしつつ画面の変更(進捗率を表示するとか)する時には DoEvents を使っていた。

今回 WPF で DoEvents があるのか?調べてみると、その物自体はなく、自分で実装して使うようになっているようだ。
この実装を行って使うという内容については、結構な件数が確認できたので、メジャーな方法というか、Microsoft のサイト自信に載っているやり方らしい。

Dispatcher.PushFrame メソッド(Microsoft)
http://msdn.microsoft.com/ja-jp/library/system.windows.threading.dispatcher.pushframe%28VS.80%29.aspx

ひとまず、ViewModel にコピペを行って確認をしてみた。
        public DelegateCommand CalculateCommand {
            get {
                if (this.calculateCommand == null) {
                    this.calculateCommand = new DelegateCommand(CalculateExecute, CanCalculateExecute);
                }
                return this.calculateCommand;
            }
        }

        private void CalculateExecute() {
            this.Message = "test message";
            DoEvents();         // ここで呼ぶ

            // 長い処理のつもり
            for(var i = 0; i < 9999; i++) {
                for(var j = 0; j< 99999; j++) {

                }
                this.Message = i.ToString();
                DoEvents();     // ここで呼ぶ
            }

            var calc = new Calculator();
            this.Answer = calc.Execute(this.Lhs, this.Rhs, this.SelectedCalculateType.CalculateType);
        }

        private bool CanCalculateExecute() {
            return this.SelectedCalculateType.CalculateType != CalculateType.None;
        }

        // ↓ ここからを追加
        public void DoEvents() {
            DispatcherFrame frame = new DispatcherFrame();
            Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
                new DispatcherOperationCallback(ExitFrames), frame);
            Dispatcher.PushFrame(frame);
        }

        public object ExitFrames(object f) {
            ((DispatcherFrame)f).Continue = false;
            return null;
        }
        // ↑ ここまで

参考にさせて頂いている様々なソースをそのままコピペの切った貼ったでの確認で、オリジナルの作者の方には申し訳無い気持ちではあるが、なんとか期待通りの動きになる事は確認できた。

わざわざの別実装なので、何か弊害がでのかも知れない点が気がかりと言えば気がかりだったりする。

0 件のコメント:

コメントを投稿