axacropdflib - 从工作线程设置源

时间:2013-11-06 19:24:54

标签: vb.net multithreading pdf worker-thread

我有一个vb.net项目,左边是pdf的树视图,右边是acrobat AxAcroPDF查看器控件。单击树视图中的项目,我获取fileinfo.fullname值并将其传递给AxAcroPDF src属性。

在测试时,我发现pdf的加载速度很慢,并且会阻止我的ui线程,所以我决定使用workerthread来帮助延迟加载这些pdf。

当我使用工作线程的DoWork方法运行我的代码并尝试更新我的pdfviewer对象时,我得到一个无效的强制转换异常。

  

发现System.InvalidCastException HResult = -2147467262
  Message =无法将“System .__ ComObject”类型的COM对象强制转换为   接口类型'AcroPDFLib.IAcroAXDocShim'。此操作失败   因为QueryInterface调用COM组件的接口   与IID'{3B813CE7-7C10-4F84-AD06-9DF76D97A9AA}'失败的原因是   以下错误:不支持此类接口(来自HRESULT的异常:   0x80004002(E_NOINTERFACE))。 Source = mscorlib StackTrace:          在System.StubHelpers.StubHelpers.GetCOMIPFromRCW(Object objSrc,IntPtr pCPCMD,IntPtr& ppTarget,Boolean& pfNeedsRelease)          at AcroPDFLib.IAcroAXDocShim.set_src(String pVal)          at AxAcroPDFLib.AxAcroPDF.set_src(String value)          at myapp.fill_treeview_with_filesfolders_docked_andthreads.LoadPDFInBackground(String   selectfile)in   C:\用户\我\桌面..... \ fill_treeview_with_filesfolders_docked_andthreads.vb:行   84 InnerException:

我无法通过此异常详细信息在线找到任何其他线程,因此我不确定这里的问题是什么。我认为我的问题与跨线程访问冲突有关,但即使我将Control.Checkforillegalcrossthreadcalls设置为false,我也会得到相同的异常。对我来说没有意义,我会检查DoWork例程中的invoke,因为我的工作线程的重点是为我处理负载,而不是将其推回到UI线程中。

任何人都可以推荐一种解决方法,我可以尝试实现我的目标吗?

我的代码:

treeview afterselect连接到displayfile

 AddHandler TreeView.AfterSelect, AddressOf displayfile

 Private Sub displayfile(sender As Object, e As TreeViewEventArgs)
    Try

        Dim selectedfile As FileInfo = New FileInfo(e.Node.Tag) 'tag has our full path embedded.

        'todo: Future - consider type of the file and load a pre-made panel with appropriate host object
        If selectedfile.Extension.ToLower.Equals(".pdf") Then
            'show "loading...."
            LoadingPanel.BringToFront()
            backgroundworker.RunWorkerAsync(selectedfile.FullName)
        End If

    Catch ex As Exception

    End Try
End Sub

后台工作人员:

#Region "Background Worker Events"
' This event handler is where the time-consuming work is done. 
Private Sub backgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As DoWorkEventArgs) Handles backgroundworker.DoWork
    Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
    e.Result = LoadPDFInBackground(e.Argument)
End Sub

' This event handler updates the progress. 
Private Sub backgroundWorker_ProgressChanged(ByVal sender As System.Object, ByVal e As ProgressChangedEventArgs) Handles backgroundworker.ProgressChanged
    ProgressBar.Value = e.ProgressPercentage
End Sub

' This event handler deals with the results of the background operation. 
Private Sub backgroundWorker_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As RunWorkerCompletedEventArgs) Handles backgroundworker.RunWorkerCompleted
    If e.Result Then
        'hide loading panel and show pdf panel
        pdfviewer.BringToFront()
    Else
        'what to do if failed to load???
    End If
End Sub
#End Region

  Private Function LoadPDFInBackground(ByVal selectedfile As String) As Boolean
    Try
        pdfviewer.src = selectedfile
        Return True
    Catch ex As Exception
        Return False
    End Try
End Function

1 个答案:

答案 0 :(得分:2)

只是一个想法,但尝试改变这一行:

pdfviewer.src = selectedfile

以下内容:

If pdfviewer.InvokeRequired Then
    pdfviewer.Invoke(Sub() pdfviewer.src = selectedfile)

它可能会解决错误。有趣的是看它是否。