2

左側にpdfのツリービューがあり、右側にacrobat AxAcroPDFビューアコントロールがあるvb.netプロジェクトがあります。ツリービューの項目をクリックすると、fileinfo.fullname の値が取得され、それが AxAcroPDF src プロパティに渡されます。

テスト中に、pdf の読み込みが遅く、UI スレッドをブロックすることに気付いたので、ワーカースレッドがこれらの pdf をバックグラウンドで遅延読み込みするのに適していると判断しました。

ワーカー スレッドの DoWork メソッドを使用してコードを実行し、pdfviewer オブジェクトを更新しようとすると、無効なキャスト例外が発生します。

System.InvalidCastException がキャッチされました HResult=-2147467262
Message='System.__ComObject' 型の COM オブジェクトをインターフェース型 'AcroPDFLib.IAcroAXDocShim' にキャストできません。IID '{3B813CE7-7C10-4F84-AD06-9DF76D97A9AA}' を持つインターフェイスの COM コンポーネントでの QueryInterface 呼び出しが次のエラーのために失敗したため、この操作は失敗しました: サポートされているそのようなインターフェイスはありません (HRESULT からの例外: 0x80004002 (E_NOINTERFACE)) . Source=mscorlib StackTrace: System.StubHelpers.StubHelpers.GetCOMIPFromRCW(Object objSrc, IntPtr pCPCMD, IntPtr& ppTarget, Boolean& pfNeedsRelease) で AcroPDFLib.IAcroAXDocShim.set_src(文字列 pVal) で AxAcroPDFLib.AxAcroPDF.set_src(文字列値) で myapp.fill_treeview_with_docked_filesfolders_folders .LoadPDFInBackground(String selectedfile) in C:\Users\me\Desktop.....

この例外の詳細を含む他のスレッドをオンラインで見つけることができないため、ここで何が問題なのかわかりません。私の問題はクロススレッドアクセス違反に関係していると思いましたが、 Control.Checkforillegalcrossthreadcalls を false に設定しても同じ例外が発生します。ワーカー スレッドの目的は負荷を処理することであり、UI スレッドに負荷を戻すことではないため、とにかく DoWork ルーチンからの invokerequired をチェックすることは意味がありませんでした。

私がここにいることを達成するために試みることができる回避策を誰かが推奨できますか?

私のコード:

ツリービュー 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
4

1 に答える 1

2

考えただけですが、次の行を変更してみてください。

pdfviewer.src = selectedfile

以下に:

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

エラーを回避できる場合があります。そうであるかどうかを確認するのは興味深いことです。

于 2013-11-06T19:47:37.083 に答える