同時かつ独立して動作する2つのタイマ

まず第一に、私は過去数週間に与えられたすべての助けを感謝したいと思います。私は1トンを学んだし、私のプログラムは毎日何時間も仕事を節約してくれました。

私はそれを少し拡張して、最初のタイマーと並行して実行されるが、最初のタイマーによって形や形に影響を受けない2番目のタイマーを追加したい。

私は最初のループで2番目のループを入れ子にしようとしましたが、2番目のループは3秒で終了します(私はthread.sleep(3000)を使用します)ので、2番目のループが終了するまで最初のループを凍結しました。私はSystem Threading(System.Timers.Timer)について読んでいました。それは私が行きたいルートのようです。

私は例としてこれを簡単に書いた:

これは、私がtimer1としてウィンドウタイマコントロールを追加したと仮定します

Option Strict On
Imports System
Imports System.Timers

Public Class form1

  Private Shared timer2 As System.Timers.Timer
  timer2 = New System.Timers.Timer
  AddHandler timer2.Elapsed, AddressOf OnTimedEvent

  Public Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
                           Handles Button1.Click
    timer1.Interval = 1000
    timer1.enabled = true
    timer2.Interval = 5000
    timer2.Enabled = True
  End sub

  Public Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) _
                         Handles Timer1.Tick
  'code for timer1 here
  End Sub

  Private Shared Sub OnTimedEvent(source As Object, e As ElapsedEventArgs)
    'code for timer2 here
  End Sub

End Class 

これは意味をなさないでしょうか... ...また、 thread.sleep のためにtimer1を使用して2回目のイベントを開始することはできません。私は、上記のコードでは、 windows.form.timer が1000 msごとに点滅している間に、2番目のスレッドをスリープ状態にすることを期待していました

2
タイマークラスはあなたを生きて食べると約束したツールボックスで使用できるTimerコンポーネントを使用し、フォームにドロップします。
追加された 著者 Hans Passant,
あなたがここで何を求めているのかを知るのは難しいです。あなたはループとスリープへの呼び出しについて言及していますが、どちらも表示しません。 timer1 の種類は明確ではありません。それが現れても、あなたのコードはコンパイルされません(そして、うまくフォーマットされません)。
追加された 著者 Gideon Engelberth,
前に指摘したように、複数のタイマーは必要ないかもしれません。
追加された 著者 dbasnett,
はい、意味がありますが、使用しているこのタイマーが結果を別のスレッドに返すことに注意してください。 Sharedは、同じオブジェクトインスタンスがスレッド間で使用可能であることを意味します。コンピュータは同時に2つのスレッドからデータを書き込むことができませんので、コードがこれをしないように注意するか、何らかのロックを実装する必要があります。たとえば、Button1のclickイベントのコード例では、共有オブジェクトにデータを書き込んでいますが、それは問題ありませんが、他にもアプリでこれを行う場合は依存します。あなたがこれから離れることができれば。非常に注意深く、データの読み書きについて考える
追加された 著者 JonAlb,

3 答え

Public Class Form1
    'a timer that fires periodically
    Dim WithEvents aTimer As New System.Threading.Timer(AddressOf TickTock, Nothing, 0, 500)
    'a stopwatch for each event
    Dim swEV1 As New Stopwatch
    Dim swEV2 As New Stopwatch
    'how long between executions
    Dim ev1Time As New TimeSpan(0, 0, 1)
    Dim ev2Time As New TimeSpan(0, 0, 5)

    'test
    Private Sub Button1_Click(sender As System.Object, _
                              e As System.EventArgs) Handles Button1.Click
        Button1.Enabled = False
        'start the test
        swEV1.Start()
        swEV2.Start()
    End Sub

    Dim ev1 As New Threading.Thread(AddressOf event1)
    Dim ev2 As New Threading.Thread(AddressOf event2)

    Private Sub TickTock(state As Object)
        If swEV1.IsRunning Then
            'check the elapsed time and run the thread when needed
            'only one thread per event is allowed to run
            If swEV1.Elapsed >= ev1Time Then
                If Not ev1.IsAlive Then
                    swEV1.Reset() 'reset the stopwatch
                    swEV1.Start()
                    ev1 = New Threading.Thread(AddressOf event1)
                    ev1.IsBackground = True
                    ev1.Start()
                End If
            End If

            If swEV2.Elapsed >= ev2Time Then
                If Not ev2.IsAlive Then
                    swEV2.Reset()
                    swEV2.Start()
                    ev2 = New Threading.Thread(AddressOf event2)
                    ev2.IsBackground = True
                    ev2.Start()
                End If
            End If

        End If
    End Sub

    Private Sub event1()
        Debug.WriteLine("EV1 " & DateTime.Now.ToString)
        Threading.Thread.Sleep(500) 'simulate work
    End Sub

    Private Sub event2()
        Debug.WriteLine("EV2 " & DateTime.Now.ToString)
        Threading.Thread.Sleep(3000) 'simulate work
    End Sub


End Class
3
追加された
dbasnett、Iveは、これを私のコードでうまく動作させるためのあらゆる可能な方法を試しました。私はあなたにvbforumに関するメッセージを送った
追加された 著者 Nefariis,
@ Nefarii - あなたのコードと質問をどこかに投稿してください。誰かがそれに答えます。
追加された 著者 dbasnett,

2つ(またはそれ以上)のタイマーを簡単に作成できます。あなたは、フォーム上にタイマーが混在していて、プログラマチックに作成したタイマーがあるようです。したがって、私が与えた例は、実行時にプログラム的に両方を作成することです。

フォームにタイマーオブジェクトを定義する:

Private Shared timer1 As System.Timers.Timer
Private Shared timer2 As System.Timers.Timer

経過イベントの2つのハンドラを定義する:

Public Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs)
'code for timer1 here
end sub

Public Sub Timer2_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs)
'code for timer2 here
end sub

ボタンをクリックすると、ハンドラを追加してタイマーを開始できます:

Public Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    'Add handlers programatically
    AddHandler timer1.Elapsed, AddressOf Timer1_Tick
    AddHandler timer2.Elapsed, AddressOf Timer2_Tick

    'Set up the timer intervals and start them
    timer1.Interval = 1000
    timer1.enabled = true
    timer2.Interval = 5000
    timer2.Enabled = True

End sub

Also it is worth reading about the different types of timers available to you in .NET

0
追加された

私はSystem.Timers.Timerについていくつかの本当に悪い経験をしていました。タイマーイベントは呼び出されません。

私はSystem.Threading.Timerをお勧めします(System.Timers.TimerがThreading.Timerのラッパーにすぎないことも知っているからです

ここで私が通常タイマーを実装する方法の例を示します

私は常にChange-Method OnceでTimerを起動し、同じTimer-Callback-Methodの複数の並列コールバックを防ぐためにCallback MethodのFinally Blockで再起動します。

Public Class Form1

   Private _Timer1 As System.Threading.Timer
   Private _Timer2 As System.Threading.Timer

   Public Sub New()

      ' This call is required by the designer.
      InitializeComponent()

      ' Add any initialization after the InitializeComponent() call.
      _Timer1 = New System.Threading.Timer(AddressOf Timer1_Callback)
      _Timer2 = New System.Threading.Timer(AddressOf Timer2_Callback)

   End Sub

   Private Sub Timer1_Callback(ByVal state As Object)
      Try

         'code for timer1 here

      Catch ex As Exception
         'Do your errorhandling
      Finally
         'Start with a delay. Just call the Callback once
         _Timer1.Change(1000, System.Threading.Timeout.Infinite)
      End Try
   End Sub
   Private Sub Timer2_Callback(ByVal state As Object)
      Try

         'code for timer2 here

      Catch ex As Exception
         'Do your errorhandling
      Finally
         'Start with a delay. Just call the Callback once
         _Timer2.Change(5000, System.Threading.Timeout.Infinite)
      End Try
   End Sub

   Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
      Try
         'Start with a delay. Just call the Callback once
         _Timer1.Change(1000, System.Threading.Timeout.Infinite)
         _Timer2.Change(5000, System.Threading.Timeout.Infinite)
      Catch ex As Exception
         'Do your errorhandling
      End Try
   End Sub
End Class
0
追加された
Imはこのオプションにかなり興味を持っていて、うまくいくはずです。しかし、まだ持っているオプションはありますか:if timer1.enabled = true? ...私は、タイマをオフにするコマンドをdisposeが表示されますが、私はタイマーが有効かどうかを知る必要があるいくつかのインスタンスがあります。
追加された 著者 Nefariis,
_Timer1.Change(System.Threading.Timeout.Infinite、System.Threading.Timeout.Infinite)を呼び出してタイマーをオフにすることができます。私が知る限り、あなたのタイマーが実行されているかどうかを確認するプロパティはありませんが、たとえば、(_Timer1Running)などのブール値フィールドに自分自身でその情報を格納し、タイマーを開始または停止する場所に値を設定できます。 Enabled = Trueを使用してTimerを有効にする場合は、独自のTimerクラスを作成することもできます。私はあなたの例を望むなら私の答えを編集することができます
追加された 著者 Nicholas,