VB.NET:线程正在运行或终止;它无法重启

时间:2014-07-22 06:48:11

标签: vb.net multithreading timer windows-services

使用多线程时遇到此错误。我是新手,在我的Windows应用程序中,此代码可以正常工作。但我把它转移到我收到的“Windows服务”“线程正在运行或终止;它无法重启”。我在Windows服务中创建它时使用的是System.Timers.Timer而不是System.Windows.Forms.Timer。这个windows服务会从数据库中导出一些XML文件,所以我需要一个计时器。因此,它会不时地检查数据库中是否有新产品或客户读取下面的功能。默认情况下,我将时间硬编码为1分钟进行测试。此外,如果函数尚未完成,我已经创建了一个布尔变量。它不会覆盖。

这是我的代码:

Dim oIsproc_BP As Boolean
Dim oIsproc_ItemMaster1 As Boolean
Dim thrd As Thread

Protected Overrides Sub onstart(ByVal args() As String)

     tmr.Interval = 1000
     AddHandler tmr.Elapsed, AddressOf tmr_Elapsed
     tmr.Start()

End Sub

Private Sub tmr_Elapsed(sender As Object, e As Timers.ElapsedEventArgs) Handles tmr.Elapsed

     oIsproc_BP = False 
     oIsproc_ItemMaster1 = False 

     tSecItemMaster.Interval = 60000'oInterval(0)
     AddHandler tSecItemMaster.Elapsed, AddressOf tSecItemMaster_Elapsed
     tSecItemMaster.Start()

     tSecCustomer.Interval = 60000'oInterval(2)
     AddHandler tSecCustomer.Elapsed, AddressOf tSecCustomer_Elapsed
     tSecCustomer.Start()

     tmr.Stop() 
End Sub


Private Sub tSecItemMaster_Elapsed(sender As Object, e As Timers.ElapsedEventArgs) Handles tSecItemMaster.Elapsed
  If Not oIsproc_ItemMaster1 Then
      oIsproc_ItemMaster1 = True
      thrd = New Thread(DirectCast(Function() oItemMaster(), ThreadStart))
      thrd.Start()
  End If
  Return
End Sub



Private Sub tSecCustomer_Elapsed(sender As Object, e As Timers.ElapsedEventArgs) Handles tSecCustomer.Elapsed
  If Not oIsproc_BP Then
      oIsproc_BP = True
      thrd = New Thread(DirectCast(Sub() oBPartners(, "C"), ThreadStart))
      thrd.Start()
  End If
  Return
End Sub

对于我的职能:

Private Function oItemMaster(Optional ByVal FirstLoad As Boolean = False, Optional oType As Integer = 1)
     ''My code here

     oIsproc_ItemMaster1 = False

End Function

Private Sub oBPartners(Optional ByVal FirstLoad As Boolean = False, Optional CardType As String = "C")
    ''My code here

     oIsproc_BP = False
End Function

1 个答案:

答案 0 :(得分:1)

您有一场比赛 - 您正在使用单个变量(thrd)来保存您可能创建的Thread的两个实例之一。考虑两个定时器同时触发,并且为定时器提供服务的线程按如下方式进行交错:

Timer 1 (tSecItemMaster_Elapsed)    Timer 2 (tSecCustomer_Elapsed)

If Not oIsproc_ItemMaster1 Then
    oIsproc_ItemMaster1 = True
                                    If Not oIsproc_BP Then
                                        oIsproc_BP = True
                                        thrd = New Thread(...)
    thrd = New Thread(...)
    thrd.Start()
End If
Return
                                        thrd.Start()
                                    End If
                                    Return

这就是您收到错误消息的原因 - 两个计时器都试图启动在Thread内创建的单个 tSecItemMaster_Elapsed对象,以及ThreadtSecCustomer_Elapsed内创建的内容从未启动过。其他中间人将引入类似的问题。

快速解决方法是创建一个单独的字段来存储每个线程。我想你可能仍然有几个竞争条件,但他们现在还没有跳出来。