Newsgroup: it.comp.lang.visual-basic
Titolo: Eseguire subroutine ad una certa ora del giorno

Salve a tutti.
Sto scrivendo un'applicazione che, a certe ore del giorno prefissate, deve
eseguire una
certa operazione. L'utente mi scrive quali sono queste ore e il mio
programma deve eseguire
una subroutine allo scoccare di una di queste ore del giorno.
Come posso fare? Ovviamente il programma deve essere in esecuzione.
Ho pensato di usare un timer abbastanza lungo (al massimo di 65535
millisecondi) che
controlla se l'ora attuale coincide con uno degli orari fissati.
Questo modo di procedere, però, ha due incovenienti:
1. 65535 millisecondi è poco più di un minuto. Magari l'utente seleziona una
sola
   ora del giorno ed io devo eseguire il controllo per 60*24 volte.
2. allo scoccare del timer è possibile che l'istante sia stato superato
(magari il programma
   è occupato a fare altro e l'evento Elapsed viene eseguito quando il
minuto indicato è
   già stato superato). In questo caso non mi accorgerei di aver superato
l'orario e non
   eseguirei la procedura.
Come fanno quei software che fanno certe cose periodicamente?

 Come fanno quei software che fanno certe cose periodicamente?
Usano lo scheduler di Windows oppure usano funzioni di Windows che mettono
il processo in attesa di un evento, come appunto il raggiungimento di una
certa ora.
--
rumplestiltskin

 ha scritto nel messaggio
news:Hr%m9.45194$e31.9...@twister2.libero.it...


 stessa cosa per gli altri eventi
Il codice postato e' incompleto in quanto se la procedura "dura" meno di
un minuto e per un caso "sfortunato" all'interno dello stesso minuto
scatta l'evento Timer 2 volte, anche la procedura viene ripetuta 2
volte. Per prevenire cio':
Option Explicit
Private mEseguiProcedura As Boolean
Private mSelOre As Integer
Private mSelMinuti As Integer
Private Sub Form_Load()
  mEseguiProcedura = True
End Sub
Private Sub tmrProcedura_Timer()
  If Hour(Time) = mSelOre And _
    Minute(Time) = mSelMinuti Then
    If mEseguiProcedura Then
      mEseguiProcedura = False
      'Esegui la procedura
    End If
  Else
    mEseguiProcedura = True
  End If
End Sub
Oppure, sfruttando il fatto che in VB le variabili booleane vengono
inizializzate a False:
Option Explicit
Private mSelOre As Integer
Private mSelMinuti As Integer
Private Sub tmrProcedura_Timer()
  Static mProceduraEseguita As Boolean
  If Hour(Time) = mSelOre And _
    Minute(Time) = mSelMinuti Then
    If Not mProceduraEseguita Then
      mProceduraEseguita = True
      'Esegui la procedura
    End If
  Else
    mProceduraEseguita = False
  End If
End Sub
Nel caso in cui, come richiesto nel post originale, vi siano piu' orari
nei quali deve essere eseguita la procedura, la cosa si fa un po' piu'
complicata.
Di primo acchitto penserei ad una doppia lista (Collection) che contiene
Orari (Stringhe "hh:mm") e Flag EseguiProcedura (Booleani). Il codice e'
sostanzialmente lo stesso:
Option Explicit
Private mSelOrari As Collection
Private mSelFlags As Collection
Private Sub Form_Load()
  Set mSelOrari = New Collection
  Set mSelFlags = New Collection
End Sub
Private Sub Form_Unload()
  Set mSelOrari = Nothing
  Set mSelFlags = Nothing
End Sub
Private Sub tmrProcedura_Timer()
  Static i As Long
  For i = 1 To mSelOrari.Count
    If Hour(Time) = Hour(mSelOrari.Item(i)) And _
      Minute(Time) = Minute(mSelOrari.Item(i)) Then
      If mSelFlags.Item(i) Then
        mSelFlags.Item(i) = False
        'Esegui la procedura
      End If
    Else
       mSelFlags.Item(i) = True
    End If
  Next i
End Sub
Il popolamento/svuotamento di tali Collection e' lasciato come esercizio
al lettore ;)
Esistono senz'altro metodi piu' efficienti, ma questo, spero(!), e' un
punto di partenza.
hth,
Lokar
--
Sito Comune: 
http://www.it-lang-vb.net/
Manifesto: 
http://www.it-lang-vb.net/docs/Manifesto.txt