3

タイマーが2回(合計2秒)刻むまで、プログラムに何も実行させようとはしていません。次のコードを使用していますが、whileステートメントを削除しないとタイマーが機能しません。

timer = 0;
Console.WriteLine("timer start ");
timer1.Start();
while (timer < 2);
Console.WriteLine("timer ends");

private void timer1_Tick(object sender, EventArgs e)
{
    Console.WriteLine(timer);
    timer++;
}
4

2 に答える 2

4

System.Timers.Timer別のスレッドで実行される を使用する必要があります 。このMSDN の記事を参照してください。

上記のリンクから:

System.Windows.Forms.Timer

メトロノームを探しているなら、間違った場所に来ています。このタイマー クラスによって発生するタイマー イベントは、Windows フォーム アプリの残りのコードに対して同期的です。これは、実行中のアプリケーション コードが、このタイマー クラスのインスタンスによってプリエンプトされることがないことを意味します (Application.DoEvents を呼び出さない場合)。

System.Timers.Timer

.NET Framework のドキュメントでは、System.Timers.Timer クラスを、マルチスレッド環境で使用するために設計および最適化されたサーバー ベースのタイマーと呼んでいます。このタイマー クラスのインスタンスは、複数のスレッドから安全にアクセスできます。System.Windows.Forms.Timer とは異なり、System.Timers.Timer クラスは既定で、共通言語ランタイム (CLR) スレッド プールから取得したワーカー スレッドでタイマー イベント ハンドラーを呼び出します。これは、Elapsed イベント ハンドラー内のコードが Win32 プログラミングのゴールデン ルールに準拠している必要があることを意味します。コントロールのインスタンスは、インスタンス化に使用されたスレッド以外のスレッドからアクセスしてはなりません

作業コード:

public partial class Form1 : Form
{
    System.Timers.Timer  tmr = new System.Timers.Timer(1000);
    volatile int timer;
    public Form1()
    {
        InitializeComponent();

    }

    private void Form1_Shown(object sender, EventArgs e)
    {
        timer = 0;

        tmr.Elapsed += new System.Timers.ElapsedEventHandler(tmr_Elapsed);
        tmr.Start();
        while (timer < 2) ;
        tmr.Stop();
        Console.WriteLine("timer ends");
    }

    void tmr_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        Console.WriteLine(timer);
        timer++;
    }
}
于 2012-11-10T05:51:55.823 に答える
3

使用しているタイマー クラスがわからない (これは重要です)。それが System.Windows.Forms.Timer のようなものであると仮定すると、ティックはメイン イベント ループでディスパッチされ、while ループでメイン イベント ループを結び付けているため、決して発生しません。GUI に関連付けられていないタイマー クラスの場合は、スレッド同期の欠如によるメモリの可視性の問題が発生している可能性があります。

また、なぜ2ティックなのか気になります。おそらくこれは単純化されたコードであり、あなたの timer_tick メソッドは実際にはもっと面白いことをしていますか? そうでない場合は、Thread.Sleep(2000) を使用できます。tick コードが何か興味深いことを行う場合、次のように tick メソッドで完了を処理できます。

timer = 0;
Console.WriteLine("timer start ");
timer1.Start();

private void timer1_Tick(object sender, EventArgs e)
{
    Console.WriteLine(timer);
    if (++timer == 2) {
      Console.WriteLine("timer ends");
      // and you probably want a timer1.Stop() in here too
    }
}
于 2012-11-10T05:32:56.727 に答える