Multithreading 如何将剪贴板放在自己的线程中以避免STA线程问题

Multithreading 如何将剪贴板放在自己的线程中以避免STA线程问题,multithreading,reporting-services,Multithreading,Reporting Services,我有一个类DLL库,它是根据我在网站上找到的一个示例构建的。该类将RTF转换为HTML。我从SQL Server Reporting Services报告中调用它。问题是代码使用的剪贴板需要自己的线程 SSRS中的错误说明: 在进行OLE调用之前,必须将当前线程设置为单线程单元(STA)模式。确保主函数上标记了STAThreadAttribute 我试图通过从互联网上找到的示例实现一个线程,但没有成功。有没有人能帮我演示一下如何获取函数的剪贴板部分并将其放在自己的线程中,然后在完成后,恢复构建H

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

SSRS中的错误说明:

在进行OLE调用之前,必须将当前线程设置为单线程单元(STA)模式。确保主函数上标记了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
公共函数sRTF_To_HTML(ByVal sRTF作为字符串)作为字符串
'声明Word应用程序对象和Word WdSaveOptions对象
将MyWord设置为Microsoft.Office.Interop.Word.Application
将更改保存为对象=_
Microsoft.Office.Interop.Word.WdSaveOptions.wdDoNotSaveChanges
'声明两个字符串以处理数据
Dim sReturnString As String=“”
Dim sConvertedString As String=“”
尝试
'实例化Word应用程序,
'将visible设置为false并创建文档
MyWord=CreateObject(“Word.application”)
MyWord.Visible=False
MyWord.Documents.Add()
'创建一个数据对象以保存富文本
'并将其复制到剪贴板
Dim doRTF作为新System.Windows.Forms.DataObject
SetData(“富文本格式”,sRTF)
'剪贴板语句从这里开始
剪贴板.SetDataObject(doRTF)
'将剪贴板的内容粘贴到空,
'隐藏Word文档
MyWord.Windows(1.Selection.Paste())
'然后,选择文档的全部内容
'并复制回剪贴板
MyWord.Windows(1.Selection.whentitory()
MyWord.Windows(1).Selection.Copy()
'现在检索DataObject的HTML属性
'存储在剪贴板上
sConvertedString=_
剪贴板.GetData(System.Windows.Forms.DataFormats.Html)
'这里是剪贴板语句的结尾
'删除某些实例中显示的某些前导文本
”(就像在Outlook中将其插入电子邮件时一样
sConvertedString=_

子字符串(“您可以创建一个新的线程对象,在启动线程之前,调用 SetApartmentState(ApartmentState.STA)
在它上面。在线程过程中,你可以访问剪贴板。

您好。谢谢您的回复。我试着按照您对整个函数所说的去做(请参阅编辑的文章),但仍然出现了错误。我只是不知道如何只对剪贴板部分执行线程。在您的新代码中,哪一行给出了异常?
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