Ikki taymer bir vaqtning o'zida va mustaqil ravishda ishlaydi

Birinchidan, men so'nggi bir necha hafta ichida berilgan yordam uchun minnatdorman. Men bir tonni o'rgandim va mening dasturim har kuni soatlab ish soati tejab qoldi.

Men uni bir oz kengaytirmoqchiman va birinchi taymerga parallel ishlaydigan ikkinchi taymerni qo'shmoqchiman, lekin birinchi taymer tomonidan hech qanday shakli yoki shakli ta'sirlanmagan.

Ikkinchi davrani dastlabki davrda joylashtirishni sinab ko'rdim, lekin ikkinchi tsiklni tugatish uchun 3 soniya davom etadi (men thread.sleep (3000) dan foydalanaman), shuning uchun ikkinchi tsikl tugaguniga qadar birinchi döngüyü muzlaganligini topdim. Tizimga ishlov berish (System.Timers.Timer) haqida o'qigan edim va bu men istagan marshrut kabi ko'rinadi.

Buni bir misol sifatida yozdim:

Bu esa, taymer1 kabi oyna taymerini boshqarish qo'shilganligini ta'kidlaydi

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 

Bu hatto mantiqiymi? ... va yana thread.sleep tufayli ikkinchi turdagi tadbirlarni o`zgartirish uchun foydalanolmayman. Yuqoridagi kod windows.form.timer har 1000 msd ni belgilashda davom etganda ikkinchi uyquni uxlashiga umid qilar edim

2
Timer sinfining sizni tiriklayin eb-ichgani haqidagi fikrga qo'shildi. Asbob qutisidagi mavjud bo'lgan Taymer komponentidan foydalaning, uni forma ustiga tashlang.
qo'shib qo'ydi muallif Hans Passant, manba
Bu erda nima so'rayotganingizni bilish qiyin. Siz looplarni eslatib, "Kutish" deb chaqirasiz, lekin bularni ham ko'rsatmang. timer1 qanday turi aniq emas. Qolaversa, sizning kodingiz ham tuzilmaydi (va yaxshi shakllanmagan).
qo'shib qo'ydi muallif Gideon Engelberth, manba
Yuqorida ta'kidlab o'tilganidek, ko'plab taymerlar talab qilinishi mumkin emas.
qo'shib qo'ydi muallif dbasnett, manba
Ha, bu mantiqan to'g'ri, ammo siz foydalanayotgan taymer sizning natijalarni alohida ishlarga qaytarishini bilib oling. Bundan tashqari, Shared bir xil ob'ekt misoli ish zarrachalari mavjudligini anglatishini unutmang. Kompyuterlar bir vaqtning o'zida ikki ish zarrachasidan ma'lumotlarni yozolmaydi, shuning uchun ehtiyot bo'lishingiz kerak, kodingiz buni qilmaydi yoki siz qulflashning bir turini amalga oshirasiz. Misol uchun, Button1 kod misolida click voqeasi birgalikda ob'ektga ma'lumotlarni yozib beradi, u yaxshi bo'lishi kerak, lekin bu narsa boshqa ilovangizda ham buni amalga oshiradi. Agar bundan uzoq tura olsa. Diqqat qiling, ma'lumotni o'qish/yozish haqida o'ylang
qo'shib qo'ydi muallif JonAlb, manba

3 javoblar

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
qo'shib qo'ydi
dbasnett, bu kodni men bilan ishlamaslik uchun har qanday usulni sinab ko'rdim. Sizga vbforum haqida xabar yubordim
qo'shib qo'ydi muallif Nefariis, manba
@ Nefarii - sizning kodingizni va boshqa joyga savol bering. Kimdir javob beradi.
qo'shib qo'ydi muallif dbasnett, manba

Sizda ikkita (yoki ko'proq) taymerni osongina olishingiz mumkin. Formada taymer taymeri va dasturiy jihatdan yaratgan taymer kabi ko'rinasiz. Shunday qilib men berilgan misol ikkalasini dasturiy ravishda ish vaqtida yaratishdir.

Shaklingizdagi taymer moslamalarni belgilang:

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

O'tgan voqealar uchun ikki ishlov beruvchini belgilang:

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

Keyin tugmani bosish bilan ishlov beruvchilarni qo'shishingiz va taymerlarni ishga tushirishingiz mumkin:

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
qo'shib qo'ydi

System.Timers.Timer bilan, masalan, masalan. Taymer-tadbir chaqirilmadi.

System.Threading.Timer (bundan tashqari, men System.Timers.Timerni faqat Threading.Timer uchun faqat bitta sarmoyador ekanligini bilganim uchun ham tavsiya qilaman).

Men odatda Timerni qanday bajarishimga misol

Taymerni har doim "O'zgartirish-usuli" bilan boshlayman va bir xil Timer-Callback-Method ning bir nechta parallel chaqiruvlarini oldini olish uchun uni qayta nolish usulining oxirgi blokida qayta ishga tushiraman.

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
qo'shib qo'ydi
Men bu variantni juda qiziqtirganman va bu ishni bajarishi kerak. Biroq, yana bir imkoniyat bor: agar timer1.enabled = true? ... Taymerni o'chirish uchun dispose buyrug'i mavjudligini ko'rdim, lekin taymer yoqilgan yoki yoqilmaganligini bilish uchun bir nechta holatlar bor.
qo'shib qo'ydi muallif Nefariis, manba
_Timer1.Change (System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite) deb chaqirish orqali taymerni o'chirishingiz mumkin. Men bilganimdek, taymer ishlayotganligini tekshirish uchun hech qanday xususiyat yo'qligini bilishingiz mumkin, biroq bu ma'lumotni Boolean Field (_Timer1Running) ichida o'zingiz saqlay olasiz va Timerni ishga tushiradigan yoki Stop ni to'xtatib turadigan qiymatni o'rnating. Taymerni faollashtirish uchun Enabled = True funksiyasini ishlatmoqchi bo'lsangiz, siz o'zingizning Taymer sinfi ham mumkin. Agar siz misolni istasangiz javobimni o'zgartirishim mumkin
qo'shib qo'ydi muallif Nicholas, manba