0

パフォーマンスのために、Threading Timer を使用して 5 秒ごとに実行される集中的なクエリを処理するために、DispatcherTimer を BackGroundWorker に置き換える必要があります。

次のコードを実装しても結果が得られなくなり、ほとんどの場合、アプリケーションもシャットダウンします。

    public void CaculateTimeBetweenWegingen()
    {          
        if (listWegingen.Count > 1)
            msStilstand = (DateTime.Now - listWegingen[listWegingen.Count - 1]).TotalSeconds;

        if(msStilstand >= minKorteStilstand) 
        {
            stopWatch.Start(); 

            if (msStilstand >= minGroteStilstand)
            {
                FillDuurStilstandRegistrationBtn();

                if (zelfdeStilstand == false)
                {
                    CreateRegistrationButton();                       
                    zelfdeStilstand = true;
                }

                if (msStilstand <= maxGroteStilstand){
                    //....
                }
            }
        }
        else //new weging
        {
            if (stopWatch.IsRunning == true)
            {
                timerStilstand.Stop();

                stopWatch.Stop();

                //huidige registrationBtn
                if (GlobalObservableCol.regBtns.Count > 1)
                {
                    GlobalObservableCol.regBtns[GlobalObservableCol.regBtns.Count - 1].StopWatchActive = false;

                    GlobalObservableCol.regBtns[GlobalObservableCol.regBtns.Count - 1].DuurStilstand =
                        String.Format("{0:D2}:{1:D2}:{2:D2}", stopWatch.Elapsed.Hours, stopWatch.Elapsed.Minutes, stopWatch.Elapsed.Seconds);
                }

            }
            zelfdeStilstand = false;
        }
    }/*CaculateTimeBetweenWegingen*/


public void CreateRegistrationButton()
    {
        InitializeDispatcherTimerStilstand();

        RegistrationButton btn = new RegistrationButton(GlobalObservableCol.regBtns.Count.ToString());
        btn.RegistrationCount = GlobalObservableCol.regBtnCount;
        btn.Title = "btnRegistration" + GlobalObservableCol.regBtnCount;
        btn.BeginStilstand = btn.Time;

        GlobalObservableCol.regBtns.Add(btn);
        GlobalObservableCol.regBtnCount++;

        btn.DuurStilstand = String.Format("{0:D2}:{1:D2}:{2:D2}", 0, 0, 0);         
    }


public void InitializeDispatcherTimerWeging()
    {
        worker = new BackgroundWorker();
        worker.DoWork += new DoWorkEventHandler(Worker_DoWork);
        worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
        worker.RunWorkerAsync();
    }

    void Worker_DoWork(object sender, DoWorkEventArgs e)
    {
        TimerCallback callback = MyTimerCallBack;
        timerWegingen = new Timer(callback);

        timerWegingen.Change(0, 5000);
    }

public void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            worker.RunWorkerAsync();
        }


    private void MyTimerCallBack(object state)
    {
        DisplayWegingInfo();
        CaculateTimeBetweenWegingen();
    }

ボタンは、別のタイマーを通じて 1 秒ごとに新しい値で補充されます。「DuurStilstand」は依存プロパティです

    private void FillDuurStilstandRegistrationBtn()
    {
        TimeSpan tsSec = TimeSpan.FromSeconds(stopWatch.Elapsed.Seconds);
        TimeSpan tsMin = TimeSpan.FromMinutes(stopWatch.Elapsed.Minutes);
        TimeSpan tsHour = TimeSpan.FromMinutes(stopWatch.Elapsed.Hours);

        if (GlobalObservableCol.regBtns.Count >= 1
                    && GlobalObservableCol.regBtns[GlobalObservableCol.regBtns.Count - 1].StopWatchActive == true)
        {
            GlobalObservableCol.regBtns[GlobalObservableCol.regBtns.Count - 1].DuurStilstand =
                            String.Format("{0:D2}:{1:D2}:{2:D2}", tsHour.Hours, tsMin.Minutes, tsSec.Seconds);
        }
    }

上記のコードはすべて別の c# クラスで記述されています。

このコードを BackGroundWorker で正確に動作させる方法と、Dispatcher/Invoke で GUI を更新する方法/場所。長い間試していましたが、この問題を解決できないようです。

また、BackGroundWorker の Complete メソッドを使用して GUI を更新できることも確認しましたが、正確な方法はわかりません。ボタンが作成され、ObservableCollection に保存されます。

 public static ObservableCollection<RegistrationButton> regBtns = new ObservableCollection<RegistrationButton>();

いくつかの例が最も役に立ちます。何をしなければならないかは多かれ少なかれ知っていますが、それを実装する方法が正確にはわかりません。

よろしく、 ジャックス

4

1 に答える 1

1

アプリの意味がわかりませんが、このように UI を更新できます

public void worker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
    {
        Application.Current.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.ApplicationIdle, new Action(() =>
        {
            //do your stuff
        }));
    }

おそらく、Rendering イベントは UIThread を処理するのに役立つはずです。

CompositionTarget.Rendering += (s, args) =>
        {
            //do your stuff
        };

それが役立つことを願っています

于 2012-04-17T20:59:27.857 に答える