读取多个stackoverflow,代码项目解决方案,无法集成到我的问题中。
在一个窗口中加载的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
选择一行,单击按钮Start,启动该行的计时器。并且通过调度程序tick事件,它会更新我已经完成的网格。现在我必须启动另一个(或两个或......)计时器,它将同时执行相同的操作。我坚持这个。让我分享一下我的尝试!
mainwindow.xaml.cs中的btnStartClickEvent
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
被发现为null。
我想知道如何保留此代码并使其适用于多个计时器。可能是多线程的。这样做的指南将非常有用。
答案 0 :(得分:0)
Thread NewThreadforStartProcessAfterTraining = new Thread(() => UpdateGrid());
NewThreadforStartProcessAfterTraining.IsBackground = true;
NewThreadforStartProcessAfterTraining.SetApartmentState(ApartmentState.STA);
NewThreadforStartProcessAfterTraining.Start();
在此上下文中,启动新STA线程的所有上述部分都是不必要的,因为您无法以这种方式更新可视树。 您可以在我以前的一个答案中找到使用STA线程的正确示例:https://stackoverflow.com/a/42473167/6996876
尝试理解WPF中线程亲和性的概念。
您只需要一个UpdateGrid()
,您必须将UI工作委派给调度员。
此外,已在此处解释将参数传递给Tick
事件:https://stackoverflow.com/a/16380663/6996876
在您的情况下,您可能希望更改当前唯一runningRow
,以便将其传递给事件。