我有一个小程序,它只不过是一个运行和更新视图的秒表。每 8 秒秒表也会在该视图上增加一个计数器。所以在 0、8、16、24 秒等...计数器是 1、2、3、4 等。
在我看来,在 XAML 中,我有几个项目,其中一个是用于保存我的秒表的 TextBlock,另一个是另一个用于显示“8 秒过去”的次数的 TextBlock。
<StackPanel Grid.Column="0" Orientation="Horizontal" HorizontalAlignment="Left" >
<Label Content="Run Time:" FontSize="16" FontWeight="Bold" Margin="10,0,0,0"/>
<TextBlock Name="ClockTextBlock" Text="00:00:00:00" FontSize="16" Foreground="Red" Margin="5" FontWeight="Bold"/>
</StackPanel>
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
<Label Content="Sample Count:" FontSize="16" FontWeight="Bold" Margin="10,0,0,0"/>
<TextBlock Text="0" Name="SampleCountDigit" Foreground="Red" FontSize="16" FontWeight="Bold" Margin="5"/>
</StackPanel>
此 xaml 文件背后的代码包含用于设置调度计时器的代码,该计时器将创建我的秒表。
public partial class StopWatchView: UserControl
{
private DispatcherTimer dt = new DispatcherTimer();
private Stopwatch stopWatch = new Stopwatch();
private string _currentTime = string.Empty;
private int _sampleCount = 0;
public StopWatchView()
{
InitializeComponent();
dt.Tick += new EventHandler(dt_Tick);
dt.Interval = new TimeSpan(0, 0, 0, 0, 1);
}
private void dt_Tick(object sender, EventArgs e)
{
if (stopWatch.IsRunning)
{
TimeSpan ts = stopWatch.Elapsed;
_currentTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds/10);
ClockTextBlock.Text = _currentTime;
if (ts.Seconds%8 == 0)
{
_sampleCount++;
SampleCountDigit.Text = _sampleCount.ToString();
}
}
}
private void StartButton_Click(object sender, RoutedEventArgs e)
{
ClockTextBlock.Foreground = Brushes.Green;
stopWatch.Start();
dt.Start();
}
问题
该代码适用于更新我的秒表,使其看起来和行为就像秒表一样。每次dt_tick()
调用和if(stopWatch.IsRunning)
评估为真时,视图都会顺利更新。我遇到问题的地方是当为真时_sampleCount
增加。if(ts.Seconds%8 == 0)
我不知道它是否是一种竞争条件(因为我仍在学习线程),但TextBox="SampleCountDigit"
更新迅速且不规律,而不是应有的 8 秒间隔。老实说,根据我对线程的了解,我不明白为什么会发生这种情况,或者当这两个成员变量(_sampleCount 和 _currentTime)都在 dt_Tick() 事件处理程序代码中更新时,为什么会成为竞争条件。
为什么会发生这种情况,我该怎么做才能更新我的 SampleCountDigit(视图),以便每 8 秒更新一次?是否应该围绕此元素的更新编写一个新线程?
编辑为了更好地了解问题的行为,当我在代码上设置断点时,SampleCountDigit.Text = _sampleCount.ToString();
在 8、16、24 秒等处完全停止......并且我视图上的 SampleDigitCounter 此后会正确更新。