ビューを実行して更新するストップウォッチにすぎない小さなプログラムがあります。8 秒ごとに、ストップ ウォッチはそのビューでもカウンターをインクリメントします。したがって、0、8、16、24 秒などで...カウンターは 1、2、3、4 などです。
ビューの XAML にはいくつかのアイテムがあります。1 つはストップウォッチを保持するための TextBlock で、もう 1 つは「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)
れて true と評価されるたびに、ビューは滞りなく更新されます。私が問題に直面しているのは、 が true のときに_sampleCount
がインクリメントされるときif(ts.Seconds%8 == 0)
です。それが競合状態であるかどうかはわかりませんが(私はまだスレッドを学習しているため)、TextBox="SampleCountDigit"
更新は8秒間隔ではなく、急速かつ不規則に行われます。正直なところ、私がスレッドについて知っていることから、これらのメンバー変数 (_sampleCount と _currentTime) の両方が dt_Tick() イベント ハンドラー コード内で更新されたときに、なぜこれが発生するのか、または競合状態になるのかがわかりません。
なぜこれが起こるのでしょうか? SampleCountDigit (ビュー) を 8 秒ごとに更新するにはどうすればよいですか? この要素の更新について新しいスレッドを作成する必要がありますか?
EDIT問題の動作をよりよく理解するためにSampleCountDigit.Text = _sampleCount.ToString();
、コードにブレークポイントを設定すると、8、16、24秒などで完全に停止します...その後、ビューのSampleDigitCounterが適切に更新されます。