wpf用于定时器应用程序的多个调度定时器:精确运行多个定时器
问题描述:
读取多个*,codeproject解决方案,无法集成到我的问题。wpf用于定时器应用程序的多个调度定时器:精确运行多个定时器
在装载在窗口中的usercontrol中有一个datagrid。 DataGrid中的每个DataRow表示一个计时器设置。
像:
timer name : Test 1 , Timer : 1h 3m
timer name : Test 2 , Timer : 2h 2m
timer name : Test 3 , Timer : 3h 1m
选择一行,点击按钮启动,启动该行的计时器。与调度员滴答事件,它更新我已完成的网格,直到此。现在我必须启动另一个(或两个或...)计时器,它将同时执行相同的操作。我困在此。让我分享我所尝试的!
btnStartClickEvent在mainwindow.xaml.cs
if (btnStart.Content.ToString() == "Start")
{
if (_AUC == ActiveUserControl.Grid)
{
runningRow = (TaskGridData)_TG.dgEmployee.SelectedItem;
if (runningRow != null)
{
currentlyRunningID.Add(runningRow.ID);
btnStart.Content = "Stop";
//worker.RunWorkerAsync(runningRow);
StartTimer(runningRow);
}
}
}
else if (btnStart.Content.ToString() == "Stop")
{
btnStart.Content = "Start";
StopTimer();
}
private DateTime TimerStart { get; set; }
private void StartTimer(TaskGridData tgd)
{
dispatcherTimer = new DispatcherTimer();
dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 1, 0);
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
TimerStart = DateTime.Now;
dispatcherTimer.Start();
//worker.RunWorkerAsync();
//string etime = DateTime.Now.Second.ToString();
}
private void StopTimer()
{
dispatcherTimer.Stop();
}
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
var currentValue = DateTime.Now - TimerStart;
runningRow.Duration = DurationValueToString(currentValue);
temp = (List<TaskGridData>)_TG.dgEmployee.ItemsSource;
foreach (TaskGridData item in temp)
{
if (item.ID == runningRow.ID)
{
item.Duration = DurationValueToString(DurationStringToVlaue(item.Duration) - DurationStringToVlaue(runningRow.Duration));
break;
}
}
//_TG.dgEmployee.ItemsSource = null;
//_TG.dgEmployee.ItemsSource = temp;
Thread NewThreadforStartProcessAfterTraining = new Thread(() => UpdateGrid());
NewThreadforStartProcessAfterTraining.IsBackground = true;
NewThreadforStartProcessAfterTraining.SetApartmentState(ApartmentState.STA);
NewThreadforStartProcessAfterTraining.Start();
}
private void UpdateGrid()
{
this.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
{
_TG.dgEmployee.ItemsSource = null;
_TG.dgEmployee.ItemsSource = temp;
}));
}
我知道这个代码是一个计时器。如果我点击第二行并尝试启动计时器,那么它在tick事件中会出错,running row
被发现为空。
我在想我该如何保持这段代码,并使其适用于多个定时器。可能是多线程。一个指导来做到这一点,将是非常有益的。
答
Thread NewThreadforStartProcessAfterTraining = new Thread(() => UpdateGrid());
NewThreadforStartProcessAfterTraining.IsBackground = true;
NewThreadforStartProcessAfterTraining.SetApartmentState(ApartmentState.STA);
NewThreadforStartProcessAfterTraining.Start();
由于无法以这种方式更新可视化树,因此您在上下文中启动新STA线程的所有上述部分都不需要和错误。 您可以在我之前的回答中找到一个使用STA线程的正确示例:https://*.com/a/42473167/6996876
尝试了解WPF中线程关联的概念。
您只需要一个UpdateGrid()
,您必须将UI工作委派给调度员。
此外,传递的参数来Tick
事件已经说明这里:https://*.com/a/16380663/6996876 在你的情况,你可能要改变目前唯一runningRow
,这样它传递给事件来代替。
我试图加我'UpgradeGrid()'方法在backgroundworker_dowork事件。并在后台升级数据网格。但是当我尝试这种方式时,它变得不可更新。 –
因为你不这样做*所有UI工作有*在* *调度。很好地阅读我的答案。 – 2017-02-28 07:43:37