如何将查询/其他密集型逻辑放置在单独的工作线程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>();
一些例子将是最有用的。因为我或多或少知道必须做什么,但不确定如何实现它。
此致敬意杰克兹
我不明白您的应用程序的含义,但您将能够像这样更新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
};
希望对你有帮助