我有一個小程序,它是不低於運行,並更新視圖秒錶等等。在該視圖中,每8秒秒錶也會增加一個計數器。因此,在0,8,16,24秒等...計數器爲1,2,3,4等。更新相同的事件處理程序中的兩個視圖UI元素產生不穩定的結果
在XAML爲我的視圖我有幾個項,其中之一是將TextBlock拿着我的秒錶,另一個是另一個TextBlock,用於顯示「8秒過去」的次數。
<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)
的計算結果爲true時,視圖都會順利更新。當我遇到問題時,當if(ts.Seconds%8 == 0)
爲真時_sampleCount
增加。我不知道它的競爭條件(因爲我仍然在學習線程),但TextBox="SampleCountDigit"
更新迅速和不正常8秒的間隔,因爲它應該。說實話,從我所知道的線程中,我不明白爲什麼會發生這種情況,或者爲什麼當dt_Tick()事件處理程序代碼中更新這兩個成員變量(_sampleCount和_currentTime)時,這將成爲競態條件。
爲什麼會變成這樣發生,我能做些什麼來更新我的SampleCountDigit(視圖),這樣每8秒,因爲它應該?應該在這個元素的更新周圍寫一個新的線程嗎?
編輯爲了提供更好的洞察問題的行爲,當我設置上SampleCountDigit.Text = _sampleCount.ToString();
一個斷點的代碼完全停止在8,16,24秒,等等...和SampleDigitCounter我此後正確查看更新。因爲您所指定的計時器的時間間隔爲1毫秒
根據您對處理器速度的說法,將會更改間隔分辨率的幫助嗎?所以,而不是毫秒,我只需設置'dt.Interval =新TimeSpan(0,0,0,1)'? –
我可能正在考慮具有> =〜50ms分辨率的Windows窗體計時器。 DispatcherTimer實際上可能會激發1000 /秒,我將不得不嘗試它。當然,如果dt_tick需要> 1ms運行,那麼這會限制你的速度。當然,將間隔設置爲1秒會更全面得多。 – Phil