如何让 sub main 表现得像 form?
How to make sub main behave like form?
VB.NET.
试图使 Sub Main
表现得像一个表单。从某种意义上说,它不会消耗处理器,并且 Sub Main
会无限期地保持 运行,定时器事件大约每秒触发一次。
下面的代码给出了我想要的行为,但我不完全理解 EventWaitHandle
是如何工作的。我的问题是......有谁知道这是否是一个好方法,或者是否有更简单的方法来拥有一个基本上什么都不做但允许触发 Timer 事件的 Sub Main?
Imports System.Threading
Module MainMod
Public Sub Main(args As String())
Dim waitHandle = New System.Threading.EventWaitHandle(True, EventResetMode.AutoReset, "", False)
Dim timer = New Timer(AddressOf OnTimerElapsed, Nothing, TimeSpan.Zero, TimeSpan.FromSeconds(1))
Do While True
waitHandle.WaitOne(TimeSpan.FromSeconds(20))
Loop
End Sub
Private Sub OnTimerElapsed(state As Object)
Debug.WriteLine(DateAndTime.Now.ToString)
End Sub
End Module
EventWaitHandle
在您的代码中确实没有做任何特别的事情。它只是让你无限等待。但是,这不是 EventWaitHandle
的标准用法。 EventWaitHandle
一般用于不同线程之间的同步。它允许一个线程等待另一个线程发出发生某事的信号。
在我看来你不需要这个功能,你只需要等待。
您可以直接调用 Console.ReadLine
。这将导致主线程等待,但如果用户输入一行,将导致应用程序退出。
另一种方法是使用Thread.Sleep
,这也会导致主线程等待。将其放入循环中将导致主线程无限期等待。
考虑以下代码:
Public Sub Main(args As String())
Dim timer = New Timer(AddressOf OnTimerElapsed, Nothing, TimeSpan.Zero, TimeSpan.FromSeconds(1))
Do While True
Thread.Sleep(TimeSpan.FromSeconds(20))
Loop
End Sub
Private Sub OnTimerElapsed(state As Object)
Debug.WriteLine(DateAndTime.Now.ToString)
End Sub
关于您的代码的另一条评论是,使用 System.Threading.Timer
class 将导致 OnTimerElapsed
被第二次调用,而如果第一次调用是需要超过一秒(计时器周期值)才能完成。
这意味着 Timer 不会等待上一次调用完成再发出新的调用。
如果这是您想要的行为,那很好。
如果没有,那么您可以用一个简单的循环替换您的应用程序并像这样使用 Thread.Sleep
:
Public Sub Main(args As String())
Do While True
Thread.Sleep(TimeSpan.FromSeconds(1))
OnTimerElapsed()
Loop
End Sub
Private Sub OnTimerElapsed()
Debug.WriteLine(DateAndTime.Now.ToString)
End Sub
VB.NET.
试图使 Sub Main
表现得像一个表单。从某种意义上说,它不会消耗处理器,并且 Sub Main
会无限期地保持 运行,定时器事件大约每秒触发一次。
下面的代码给出了我想要的行为,但我不完全理解 EventWaitHandle
是如何工作的。我的问题是......有谁知道这是否是一个好方法,或者是否有更简单的方法来拥有一个基本上什么都不做但允许触发 Timer 事件的 Sub Main?
Imports System.Threading
Module MainMod
Public Sub Main(args As String())
Dim waitHandle = New System.Threading.EventWaitHandle(True, EventResetMode.AutoReset, "", False)
Dim timer = New Timer(AddressOf OnTimerElapsed, Nothing, TimeSpan.Zero, TimeSpan.FromSeconds(1))
Do While True
waitHandle.WaitOne(TimeSpan.FromSeconds(20))
Loop
End Sub
Private Sub OnTimerElapsed(state As Object)
Debug.WriteLine(DateAndTime.Now.ToString)
End Sub
End Module
EventWaitHandle
在您的代码中确实没有做任何特别的事情。它只是让你无限等待。但是,这不是 EventWaitHandle
的标准用法。 EventWaitHandle
一般用于不同线程之间的同步。它允许一个线程等待另一个线程发出发生某事的信号。
在我看来你不需要这个功能,你只需要等待。
您可以直接调用 Console.ReadLine
。这将导致主线程等待,但如果用户输入一行,将导致应用程序退出。
另一种方法是使用Thread.Sleep
,这也会导致主线程等待。将其放入循环中将导致主线程无限期等待。
考虑以下代码:
Public Sub Main(args As String())
Dim timer = New Timer(AddressOf OnTimerElapsed, Nothing, TimeSpan.Zero, TimeSpan.FromSeconds(1))
Do While True
Thread.Sleep(TimeSpan.FromSeconds(20))
Loop
End Sub
Private Sub OnTimerElapsed(state As Object)
Debug.WriteLine(DateAndTime.Now.ToString)
End Sub
关于您的代码的另一条评论是,使用 System.Threading.Timer
class 将导致 OnTimerElapsed
被第二次调用,而如果第一次调用是需要超过一秒(计时器周期值)才能完成。
这意味着 Timer 不会等待上一次调用完成再发出新的调用。
如果这是您想要的行为,那很好。
如果没有,那么您可以用一个简单的循环替换您的应用程序并像这样使用 Thread.Sleep
:
Public Sub Main(args As String())
Do While True
Thread.Sleep(TimeSpan.FromSeconds(1))
OnTimerElapsed()
Loop
End Sub
Private Sub OnTimerElapsed()
Debug.WriteLine(DateAndTime.Now.ToString)
End Sub