0

私が取り組んでいるプロジェクトにタイマーを実装しています。ボタンが押されるたびにタイマーが起動します。

最初に押すと、タイマーの期間が設定され、タイマーが開始されます。タイマーが刻むたびに、プログラムは期間を減らして画面に出力します。それは完全に機能します...タイマーの実行中にもう一度ボタンを押すまで。これを行うと、tick イベントのアクションは、実行中にボタンを押した回数だけ発生します。

私のXAMLは次のようになります。

<Grid Grid.Row="1">
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <TextBlock x:Name="tBox" Text="TIMER" Grid.Row="0" HorizontalAlignment="Center" Style="{StaticResource PhoneTextTitle2Style}"/>
    <TextBlock x:Name="timer" Text="00"  Grid.Row="1" HorizontalAlignment="Center" Style="{StaticResource PhoneTextTitle1Style}"/>
</Grid>

<Button 
    Grid.Row="1" 
    Grid.Column="0"
    Content="Online" 
    HorizontalAlignment="Center"
    Width="200"
    Height="75" Click="trigger" />

そして私のC#は次のようになります:

public partial class MainPage : PhoneApplicationPage
{
    int duration = 0;
    int converted = 0;
    int count = 0;
    DispatcherTimer tmr = new DispatcherTimer();

    // Constructor
    public MainPage()
    {
        InitializeComponent();
    }

    private void trigger(object sender, RoutedEventArgs e)
    {
        resetTimer();
        timer.Text = "30";
        tmr.Interval = TimeSpan.FromSeconds(1);
        tmr.Tick += OnTimerTick;
            tmr.Start();
    }

    void OnTimerTick(object sender, EventArgs args)
    {
        converted = duration - 1;
        timer.Text = converted.ToString();
        duration = converted;
        tBox.Text = strConvert;
        count = count + 1;
        if (duration == 0)
        {
            tmr.Stop();
        }
    }

    void resetTimer()
    {
        count = 0;
        DispatcherTimer tmr = new DispatcherTimer();
        tmr.Interval = TimeSpan.FromSeconds(0);
        duration = 30;
        converted = 0;
        tmr.Stop();
    }
}
4

3 に答える 3

2

Tickメソッドにイベントのハンドラーを追加しないでください。イベント ハンドラーを追加しTick、間隔を設定し、ウィンドウが作成されたときに (つまり、コンストラクターで) タイマーを作成し、ボタンが押されたときにタイマーだけを作成しますStart

また、ボタンが押されたときに新しいタイマーを作成しないでください。既存のタイマーを再利用できますし、再利用する必要があります。

実際にタイマーを複数回起動しているわけではありません。何が起こっているかというとTick、ボタンを押すたびに同じメソッドをハンドラーとしてイベントに追加しているため、メソッドが何度も呼び出されるとイベントTickが発生するということです。すでに実行されているタイマーを呼び出しても、複数回起動することはありません。間隔がリセットされるだけです(これが望ましいと思います)。Start

于 2013-01-07T19:08:05.280 に答える
0

既存のタイマーを閉じる前に新しいタイマー参照を作成しないようにリセット メソッドを書き直します。

void resetTimer()
{
    count = 0;
    tmr.Stop();
    tmr.Interval = TimeSpan.FromSeconds(0);
    duration = 30;
    converted = 0;
}

同様に、ページの読み込み時に Tick イベント ハンドラーを設定します。

// Constructor
public MainPage()
{
    InitializeComponent();
    timer.Text = "30";
    tmr.Interval = TimeSpan.FromSeconds(1);
    tmr.Tick += OnTimerTick;
}

private void trigger(object sender, RoutedEventArgs e)
{
        resetTimer();
        tmr.Start();
}

なおさら、

tick メソッドの実行に時間がかかる場合に複数回実行しても問題ない場合を除き、tick メソッドの実行中はタイマーを停止する必要があります。

    void OnTimerTick(object sender, EventArgs args)
    {
tmr.Stop();        
converted = duration - 1;
        timer.Text = converted.ToString();
        duration = converted;
        tBox.Text = strConvert;
        count = count + 1;
tmr.Start();
    }
于 2013-01-07T19:09:22.507 に答える
0

問題は、trigger() が呼び出されるたびに OnTimerTick ハンドラー メソッドの新しいインスタンスを追加していることです。これは、ユーザーがボタンをクリックするたびにその署名から推測されます。

私は2つのことのいずれかを行います。ユーザーが複数回クリックできないように、trigger() メソッド本体のボタンを削除/無効にするか、Tick イベントをチェックして、OnTimerTick への参照をアタッチする前に null (ハンドラーがない) であることを確認します。

于 2013-01-07T19:09:32.243 に答える