何时使用暴露给VB6的Component时设置ThreadApartmentState

时间:2011-01-25 06:58:27

标签: .net multithreading com vb6

我有一个COM组件,我正在修复VB6应用程序(和引发事件)中使用的主机VB6程序。

此Component使用Multiple Threads在内部执行它的工作,然后将事件移出到实际暴露给VB6应用程序的层。

在通过VB6应用程序(New MyObject)调用的Component的构造函数中,组件中的这段代码被调用

public sub New()
  mSyncContext = System.Threading.SynchronizationContext.Current
  If mSyncContext Is Nothing Then
      Using f As New Windows.Forms.Form
         mSyncContext = System.Threading.SynchronizationContext.Current
      End Using
  End If
end sub 

在他们提出的线程中,在这个外部对象中接收。

事件最终会进入CommsCommunicationsError,然后执行一些技巧将其置于正确的线程上以将事件引发到VisualBasic6中。

Private Sub CommsCommunicationsError(ByVal theErrorNumber As Integer, ByVal theOrder As Order)
  mRecordingCounter += 1

  Dim args As OrderErrorEventArgs
  If theOrder.Parent IsNot Nothing Then
      args = New OrderErrorEventArgs(theErrorNumber, theOrder.Parent, mRecordingCounter)
  Else
      args = New OrderErrorEventArgs(theErrorNumber, theOrder, mRecordingCounter)
  End If

  PostToCommunicationsError(args)
End Sub

Private Sub PostToCommunicationsError(ByVal args As OrderErrorEventArgs)
  mSyncContext.Post(AddressOf CommunicationsErrorSend, args)
End Sub

Private Sub CommunicationsErrorSend(ByVal state As Object)
  Dim args As OrderErrorEventArgs = CType(state, OrderErrorEventArgs)
  onCommunicationsError(args)
End Sub

Private Sub onCommunicationsError(ByVal args As OrderErrorEventArgs)
  RaiseEvent CommunicationsError(args.ErrorNumber, args.Order)
End Sub

这是应该如何完成的,因为我有时会在应用程序中发现其中一个事件时会出现随机崩溃。

线程是否应将其公寓状态更改为STA(可能)而不是MTA(默认值)?

2 个答案:

答案 0 :(得分:0)

是的,也许是the threads should be STA

答案 1 :(得分:0)

我发现,对于这个问题的解决方案,没有要求改变线程模型。这些问题与多线程无关。在它自己的线程中运行的网络代码正在创建异常并导致主线程失败(即使它不应该)

删除上下文发布代码一致导致看起来像是同一件事的错误(性质不同),但它们是一致的而不是像网络代码一样随机。

IMO我建议单独留下线程公寓(使用默认值)。