0

为了提高性能,我必须用 BackGroundWorker 替换 DispatcherTimer 来处理使用线程计时器每 5 秒运行一次的密集查询。

实现以下代码时,我不再得到任何结果,大多数时候我的应用程序也会关闭。

    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
        }));
    }

也许渲染事件应该可以帮助您处理 UIThread。

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

希望有帮助

于 2012-04-17T20:59:27.857 回答