为什么AutoResetEvent导致内存错误?

时间:2013-01-21 19:52:59

标签: vb.net multithreading service out-of-memory autoresetevent

下面,您将找到我最新编码心痛的来源。它是基类中的一个小方法,它在辅助线程中运行派生类的方法。此代码在Windows服务中运行大约5次,每5分钟启动一次。

Private Sub performAction(ByVal startedAt As DateTime)
    Dim waiter As New System.Threading.AutoResetEvent(False)
    Try
        Dim statusTimeout As Short = DefaultTimeOutSeconds
        Dim action As Threading.Thread = New Threading.Thread(AddressOf ActionToPerform)
        Dim configHelper As New ApplicationHelper.SST_CONFIG()
        Short.TryParse(configHelper.GetConfig(String.Format("{0}.Timeout", ActorType), DefaultTimeOutSeconds), statusTimeout)
        action.SetApartmentState(System.Threading.ApartmentState.STA)
        action.Priority = Threading.ThreadPriority.Highest
        action.Start()
        While LastUpdated < startedAt AndAlso DateTime.Now <= startedAt.AddSeconds(statusTimeout)
            waiter.WaitOne(1000)
        End While
    Finally
        waiter.Close()
    End Try
End Sub

它会运行一段时间。最终它耗尽了内存。从那时起,在重新启动服务之前会抛出内存错误。实际抛出错误的文本如下:

System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at System.Threading.WaitHandle.WaitOneNative(SafeHandle waitableSafeHandle, UInt32 millisecondsTimeout, Boolean hasThreadAffinity, Boolean exitContext)
at System.Threading.WaitHandle.InternalWaitOne(SafeHandle waitableSafeHandle, Int64 millisecondsTimeout, Boolean hasThreadAffinity, Boolean exitContext)
at System.Threading.WaitHandle.WaitOne(Int32 millisecondsTimeout, Boolean exitContext)
at System.Threading.WaitHandle.WaitOne(Int32 millisecondsTimeout)
at DeviceManagement.AsynchronousDeviceAction.performAction(Thread& action, DateTime startedAt)
at DeviceManagement.AsynchronousDeviceAction.Perform()
at DeviceManagement.PAJournalPrinter.GetStatus();

在我开始使用AutoResetEvent控制while循环之前,这些错误并没有真正开始。我用来使用System.Threading.Thread.Sleep。但是,当我使用sleep方法时,我调用的其中一个com对象将不会运行。更改为AutoResetEvent使代码运行,但即使调用com对象的方法不是要运行的派生类之一,内存错误现在也会显示出来。

请帮忙。 :)

1 个答案:

答案 0 :(得分:0)

回到system.threading.thread.sleep解决了我的问题。只有需要AutoResetEvent才能工作的设备才使用AutoResetEvent。记忆错误已经过去了。