如何将查询/其他密集型逻辑放置在单独的工作线程BackGroundWorker中

本文关键字:单独 工作 BackGroundWorker 线程 查询 其他 密集型 | 更新日期: 2023-09-27 18:31:20

为了提高性能,我必须将DispatcherTimer替换为BackGroundWorker 以使用线程计时器处理每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 一起工作,以及如何/在哪里使用调度程序/调用更新GUI。已经尝试了很长时间,我似乎无法解决这个问题。

我还看到BackGroundWorker 的 Complete 方法可用于更新 GUI,但不确定具体如何更新。按钮被创建并保存在可观察集合中。

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

一些例子将是最有用的。因为我或多或少知道必须做什么,但不确定如何实现它。

此致敬意杰克兹

如何将查询/其他密集型逻辑放置在单独的工作线程BackGroundWorker中

我不明白您的应用程序的含义,但您将能够像这样更新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
        }));
    }

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

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

希望对你有帮助