异步和COM对象

时间:2014-02-26 17:19:29

标签: vb.net asynchronous

我有一个具有长时间运行的Active Directory查询的程序。我想利用VB.NET的Async技术,但当我将我的函数转换为Async时,我开始得到一个InvalidCastException。当我切换回来时,错误消失了。为什么Async会导致我的COM对象出现InvalidCastException?

异常消息:

  

无法将“System .__ ComObject”类型的COM对象强制转换为接口类型“IDirectorySearch”。此操作失败,因为对IID为“{109BA8EC-92F0-11D0-A790-00C04FD8D5A8}”的接口的COM组件的QueryInterface调用由于以下错误而失败:不支持此类接口(HRESULT异常:0x80004002(E_NOINTERFACE))

这必须发生在核心库中的某个地方,因为我的代码中没有对IDirectorySearch的任何引用。实际上,堆栈跟踪并不是很有启发性:

enter image description here

这是抛出异常的地方(根据调试器):

Private Overloads Sub OnPropertyChanged(propertyName As String)
    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub

这是实际的代码。我创建了两个版本来演示代码之前(FindAll1)和之后(FindAll2)异步:

Private Async Sub FindAllButton_Click(sender As Object, e As RoutedEventArgs) Handles FindAllButton.Click
    'Me.Entries = Await FindAll1(Me.FilterText) ' Works
    Me.Entries = Await FindAll2(Me.FilterText) ' Doesn't Work
End Sub

Private Async Function FindAll1(filterText As String) As Task(Of IEnumerable(Of DirectoryEntryWrapper))
    Dim l_searcher As New DirectorySearcher()
    l_searcher.SizeLimit = Me.QuerySizeLimit
    l_searcher.Filter = filterText

    Me.IsLoading = True
    Dim l_results =
        From result In l_searcher.FindAll().Cast(Of SearchResult)()
        Select entry =
            New DirectoryEntryWrapper(result.GetDirectoryEntry(), AddressOf DirectoryEntryWrapperEventHandler)
        Order By entry.Name
    Me.IsLoading = False

    Return l_results
End Function

Private Async Function FindAll2(filterText As String) As Task(Of IEnumerable(Of DirectoryEntryWrapper))
    Dim l_searcher As New DirectorySearcher()
    l_searcher.SizeLimit = Me.QuerySizeLimit
    l_searcher.Filter = filterText

    Me.IsLoading = True
    Dim l_results =
        Await Task.Run(
            Function() _
                From result In l_searcher.FindAll().Cast(Of SearchResult)()
                Select entry =
                    New DirectoryEntryWrapper(result.GetDirectoryEntry(), AddressOf DirectoryEntryWrapperEventHandler)
                Order By entry.Name
            )
    Me.IsLoading = False

    Return l_results
End Function

0 个答案:

没有答案