2016-01-04 45 views
1

我有一個簡單的WinForm應用程序。該應用程序的主要入口點是mainForm。我正在使用窗體上的定時器,定時器間隔設置爲2000毫秒。定時器的Tick事件如下,定時器,可以從一個類中調用並形成

Public myValue as Integer = 100 

Private Sub myTimer_Tick(sender As Object, e As EventArgs) Handles myTimer.Tick 
    If myValue = 0 Then 
     myTimer.Enabled = False 
    Else 
     myValue = myValue -1 
    End If 
End Sub 

定時器在加載mainForm時在應用程序的開始被調用。現在myValue是一個全局變量,在這裏爲了簡單起見,我已經使用了它,否則它被一些進程計數機制取代,這不需要在這裏解釋。

我能夠使用這種方法,只要我使用Windows.Forms.Timer放置在一些特定的窗體上。這種方法失敗了,我還有兩種情況。

1 - 我必須在其他窗體上使用相同的功能,爲此目前我在另一個窗體上使用單獨的Timer,並且它有自己的Tick事件。

2 - 我必須從另一個模塊/類使用相同的功能,我無法實現這一點,因爲爲了這個工作,我需要一個窗體。

現在,我已經看到了Threading.Timer。我面臨的問題是,我不知道如何等待Threading.Timer完成,因爲在調用Threading.Timer之後,控件會轉到下一行。我不確定這是否可以在WaitHandle的幫助下完成。另外我讀過Threading.Timer爲它的每個Tick創建一個單獨的Thread。這在我的簡單情況下似乎是一種矯枉過正的行爲。

我只想使用Timer功能而不需要Form。另外,我可以使用帶有Thread.Sleep的Do Loop創建類似的功能,但除非我確定我的Timer功能在其他情況下不起作用,否則我將堅持使用Timer方法。

+1

還有一個'System.Timers.Timer'。考慮到你寫的一些東西,使用一個班級來完成獨立於 – Plutonix

回答

1

我明白了......如果是這樣的話,你應該真的創建第二個線程,運行一個循環。該線程有一些退出參數,指示操作已完成,線程本身設置爲Isbackground = false。

但是,你也可以做到這一點...

Imports System.Timers 

Public Class Main 

    Private Shared WithEvents m_oTimer As Timers.Timer = Nothing 

    Private Shared m_oWaitHandle_TimerHasCompleted As System.Threading.AutoResetEvent = Nothing 

    Public Shared Sub Main() 

     Try 
      'Application Entry point ... 

      'Create the global timer 
      m_oTimer = New Timers.Timer 
      With m_oTimer 
       .AutoReset = True 
       .Interval = 2000 

       .Start() 
      End With 
      'Create the WaitHandle 
      m_oWaitHandle_TimerHasCompleted = New System.Threading.AutoResetEvent(False) 

      'Show your form 
      Dim oFrm As New Form1 
      Application.Run(oFrm) 

      'Wait for the timer to also indicate that it has finished before exiting 
      m_oWaitHandle_TimerHasCompleted.WaitOne() 

     Catch ex As Exception 
      'Error Handling here ... 
     End Try 

    End Sub 

    Private Shared Sub m_oTimer_Elapsed(sender As Object, e As ElapsedEventArgs) Handles m_oTimer.Elapsed 
     'Timer will fire here ... 
     Try 
      If 1 = 2 Then 
       m_oWaitHandle_TimerHasCompleted.Set() 
      End If 

     Catch ex As Exception 
      'Error Handling ... 
     End Try 
    End Sub 
End Class 

請注意,「m_oWaitHandle_TimerHasCompleted.Set()」將永遠不會運行,你必須添加一個條件......然而,一旦運行,WaitOne將完成並且應用程序將根據需要退出。

Hows zat?

+0

太好了。對我來說是一個好的方向。 –

0

聽起來像你想創建一個計時器的單個實例,這不需要通過窗體實例化?

如果是這樣......創建一個名爲'Main'的新類並將以下內容複製到其中。

Imports System.Timers 

Public Class Main 

    Private Shared WithEvents m_oTimer As Timers.Timer = Nothing 

    Public Shared Sub Main() 

     Try 
      'Application Entry point ... 

      'Create the global timer 
      m_oTimer = New Timers.Timer 
      With m_oTimer 
       .AutoReset = True 
       .Interval = 2000 

       .Start() 
      End With 

      'Show your form 
      Dim oFrm As New Form1 
      Application.Run(oFrm) 

     Catch ex As Exception 
      'Error Handling here ... 
     End Try 

    End Sub 

    Private Shared Sub m_oTimer_Elapsed(sender As Object, e As ElapsedEventArgs) Handles m_oTimer.Elapsed 
     'Timer will fire here ... 
     Try 

     Catch ex As Exception 
      'Error Handling ... 
     End Try 
    End Sub 
End Class 

完成後,右鍵單擊您的項目並選擇'屬性'。在應用程序選項卡中,您會看到一個名爲「啓用應用程序框架」的複選框。取消選中此框。現在,在名爲「Startup Object」的下拉菜單中,您現在應該看到「Sub Main」....選擇該選項。

當應用程序運行時,Sub Main現在將運行而不是您的表單。

這將創建將在您的表單之外觸發的Timer。請注意,因爲你沒有同步它,所以我相信它會在一個線程內運行,所以要小心一點:)

+0

的時間是非常有意義的。謝謝你的迴應。您提出的解決方案解決了我的一個問題。另一個問題仍然是一樣的。正如問題中提到的,我想要一個全局定時器(您已經提供),其次我想等待定時器完成或處理。因此,例如,如果在您提出的解決方案中,我不啓動並運行oFrm並刪除Application.Run(oFrm)行,那麼應用程序將退出。我想要的是,如果Timer正在運行,那麼應用程序不應該退出。 –

相關問題