如何将Clipboard放在自己的线程中以避免STA线程问题

时间:2014-11-03 16:00:47

标签: multithreading reporting-services

我有一个类DLL库,我是根据我在网站上找到的样本构建的。该类将RTF转换为HTML。我从我的SQL Server Reporting Services报告中调用它。问题是代码正在使用需要自己的线程的剪贴板。

SSRS中的错误说明:

在进行OLE调用之前,必须将当前线程设置为单线程单元(STA)模式。确保您的Main函数标记了STAThreadAttribute。

我尝试通过互联网上找到的样本实现一个线程无济于事。有些帮助可以告诉我如何获取函数的剪贴板片段并将其放在自己的线程中,然后在完成后,恢复构建HTML字符串的函数,将其发送回我的SSRS报告吗?

这是功能:

Public Function sRTF_To_HTML(ByVal sRTF As String) As String
    'Declare a Word Application Object and a Word WdSaveOptions object
    Dim MyWord As Microsoft.Office.Interop.Word.Application
    Dim oDoNotSaveChanges As Object = _
         Microsoft.Office.Interop.Word.WdSaveOptions.wdDoNotSaveChanges
    'Declare two strings to handle the data
    Dim sReturnString As String = ""
    Dim sConvertedString As String = ""
    Try
        'Instantiate the Word application,
        'set visible to false and create a document
        MyWord = CreateObject("Word.application")
        MyWord.Visible = False
        MyWord.Documents.Add()
        'Create a DataObject to hold the Rich Text
        'and copy it to the clipboard
        Dim doRTF As New System.Windows.Forms.DataObject
        doRTF.SetData("Rich Text Format", sRTF)

        'HERE IS WHERE THE CLIPBOARD STATEMENTS BEGIN


        Clipboard.SetDataObject(doRTF)
        'Paste the contents of the clipboard to the empty,
        'hidden Word Document
        MyWord.Windows(1).Selection.Paste()
        '…then, select the entire contents of the document
        'and copy back to the clipboard
        MyWord.Windows(1).Selection.WholeStory()
        MyWord.Windows(1).Selection.Copy()
        'Now retrieve the HTML property of the DataObject
        'stored on the clipboard
        sConvertedString = _
             Clipboard.GetData(System.Windows.Forms.DataFormats.Html)

        'HERE IS WHERE THE CLIPBOARD STATEMENTS END


        'Remove some leading text that shows up in some instances
        '(like when you insert it into an email in Outlook
        sConvertedString = _
             sConvertedString.Substring(sConvertedString.IndexOf("<html"))
        'Also remove multiple  characters that somehow end up in there
        sConvertedString = sConvertedString.Replace("Â", "")
        '…and you're done.
        sReturnString = sConvertedString
        If Not MyWord Is Nothing Then
            MyWord.Quit(oDoNotSaveChanges)
            MyWord = Nothing
        End If
    Catch ex As Exception
        If Not MyWord Is Nothing Then
            MyWord.Quit(oDoNotSaveChanges)
            MyWord = Nothing
        End If
        MsgBox("Error converting Rich Text to HTML")
    End Try
    Return sReturnString
End Function

我将函数放入线程的尝试不起作用。虽然我在使用表单项目调用我的解决方案中测试DLL时没有出现线程错误,但是从SQL Server Reporting Services报告中调用它时仍然会出现线程错误。

我尝试了以下线程并且无效。

Imports System.IO
Imports System.Threading
Imports System.Windows.Forms
Imports System.Collections.Generic
Imports System.Runtime.InteropServices

<AttributeUsage(AttributeTargets.Method)> _
Public NotInheritable Class clsGetHTMLfromRTF
   Inherits Attribute

   Private Sub New()
   End Sub

   <STAThread()> _
   Public Shared Function TranlslateRTFtoHTML(ByVal rtfText As String) As String
      Dim thread = New Thread(AddressOf ConvertRtfInSTAThread)
      Dim threadData = New ConvertRtfThreadData() With {.RtfText = rtfText}

      thread.SetApartmentState(ApartmentState.STA)
      thread.isBackground = True
      thread.Start(threadData)
      thread.Join()
      Return threadData.HtmlText
   End Function

   Public Shared Sub ConvertRtfInSTAThread(ByVal rtf As Object)
      Dim threadData = TryCast(rtf, ConvertRtfThreadData)
      threadData.HtmlText = sRTF_To_HTML(threadData.RtfText)
   End Sub

   Public Class ConvertRtfThreadData
      Public Property RtfText() As String
         Get
            Return m_RtfText
         End Get
         Set(ByVal value As String)
            m_RtfText = value
         End Set
      End Property

      Private m_RtfText As String
      Public Property HtmlText() As String
         Get
            Return m_HtmlText
         End Get
         Set(ByVal value As String)
            m_HtmlText = value
         End Set
      End Property
      Private m_HtmlText As String
   End Class

   Public Shared Function sRTF_To_HTML(ByVal sRTF As String) As String
      'Declare a Word Application Object and a Word WdSaveOptions object
      Dim MyWord As Microsoft.Office.Interop.Word.Application
      Dim oDoNotSaveChanges As Object = _
           Microsoft.Office.Interop.Word.WdSaveOptions.wdDoNotSaveChanges
      'Declare two strings to handle the data
      Dim sReturnString As String = ""
      Dim sConvertedString As String = ""
      Try
         'Instantiate the Word application,
         'set visible to false and create a document
         MyWord = CreateObject("Word.application")
         MyWord.Visible = False
         MyWord.Documents.Add()
         'Create a DataObject to hold the Rich Text
         'and copy it to the clipboard
         Dim doRTF As New System.Windows.Forms.DataObject
         doRTF.SetData("Rich Text Format", sRTF)
         Clipboard.SetDataObject(doRTF)
         'Paste the contents of the clipboard to the empty,
         'hidden Word Document
         MyWord.Windows(1).Selection.Paste()
         '…then, select the entire contents of the document
         'and copy back to the clipboard
         MyWord.Windows(1).Selection.WholeStory()
         MyWord.Windows(1).Selection.Copy()
         'Now retrieve the HTML property of the DataObject
         'stored on the clipboard
         sConvertedString = _
              Clipboard.GetData(System.Windows.Forms.DataFormats.Html)
         'Remove some leading text that shows up in some instances
         '(like when you insert it into an email in Outlook
         sConvertedString = _
              sConvertedString.Substring(sConvertedString.IndexOf("<html"))
         'Also remove multiple  characters that somehow end up in there
         sConvertedString = sConvertedString.Replace("Â", "")
         '…and you're done.
         sReturnString = sConvertedString
         If Not MyWord Is Nothing Then
            MyWord.Quit(oDoNotSaveChanges)
            MyWord = Nothing
         End If
      Catch ex As Exception
         Return ex.Message
         If Not MyWord Is Nothing Then
            MyWord.Quit(oDoNotSaveChanges)
            MyWord = Nothing
         End If
         'MsgBox("Error converting Rich Text to HTML" & vbCrLf & ex.Message)
      End Try
      Return sReturnString
   End Function
End Class

1 个答案:

答案 0 :(得分:0)

您可以创建一个新的Thread对象,在启动该线程之前,请调用     SetApartmentState(ApartmentState.STA) 在上面。在线程过程中,您可以访问剪贴板。