1

我正在尝试使用 MSDN 中的这个在 RTF 和 HTML库之间转换来将一些 RTF 文本转换为 HTML。我的设置的要点是从 JavaScript 到 C# 处理程序的 AJAX 调用,该处理程序调用此MarkupConverter库进行转换,然后写回 HTML。

这是我的 JavaScript:

$.ajax({
   type: "POST",
   url: "MyHandler.ashx",
   data: richTextData,
   success: function (html) {
            alert('success, html: ' + html);
   },
   error: function (msg) {
            alert("error: " + msg);
   }
});

还有我的处理程序的代码,也很简单:

public void ProcessRequest(HttpContext context)
{
   if (context.Request.Form.Count > 0)
   {
      string rtf = context.Request.Form[0];
      string html = "";
      if (rtf != "")
      {
         markupConverter = new MarkupConverter.MarkupConverter();
         html = markupConverter.ConvertRtfToHtml(rtf);
      }
      if (html != "")
      {
         context.Response.ContentType = "text/html";
         context.Response.Write(html);
      }
      else
      {
         context.Response.ContentType = "text/plain";
         context.Response.Write("Error from RTF2HTML");
      }
   }
}

问题是,每次运行时,都会抛出异常,因为RichTextBox控件是在后台线程上创建的:

[InvalidOperationException: 调用线程必须是 STA,因为很多 UI 组件都需要这个。]
System.Windows.Input.InputManager..ctor() +11032206
System.Windows.Input.InputManager.GetCurrentInputManagerImpl() +125
System.Windows.Input .KeyboardNavigation..ctor() +185
System.Windows.FrameworkElement.EnsureFrameworkServices() +109
System.Windows.FrameworkElement..ctor() +504
System.Windows.Controls.Control..ctor() +87
System.Windows。 Controls.RichTextBox..ctor(FlowDocument 文档) +56
MarkupConverter.RtfToHtmlConverter.ConvertRtfToXaml(String rtfText) +67 MarkupConverter.RtfToHtmlConverter.ConvertRtfToHtml(String rtfText) +23 MyHandler.ProcessRequest(HttpContext context) +416

我想可能是因为 AJAX 调用是异步的,所以调用被放置在后台线程上。所以我把它改成这样:

var postText = $.ajax({
   type: "POST",
   url: "RTF2HTML.ashx",
   data: textData,
   async: false
}).responseText;
alert(postText);

但即使当我检查处理程序中的当前线程时:

context.Response.Write("thread: " + System.Threading.Thread.CurrentThread.GetApartmentState().ToString());

它仍然返回 MTA。

有没有办法连接到主 STA 线程,或者我必须创建一个新线程并指定 STA?如果是这种情况,我该如何设置回调函数以按照Response.Write当前的方式返回我的 HTML?

4

2 回答 2

3

这可能有用:

如何在 STA 线程中运行某些东西?

也许你可以打电话给...

html = markupConverter.ConvertRtfToHtml(rtf);

...以相同的方式在不同的线程上?

string rtf;

public void ProcessRequest(HttpContext context)
{
   if (context.Request.Form.Count > 0)
   {
      rtf = context.Request.Form[0];
      string html = "";
      if (rtf != "")
      {
         Thread thread = new Thread(ConvertMarkup);
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
            thread.Join();
      }
      if (html != "")
      {
         context.Response.ContentType = "text/html";
         context.Response.Write(html);
      }
      else
      {
         context.Response.ContentType = "text/plain";
         context.Response.Write("Error from RTF2HTML");
      }
   }
}

void ConvertMarkup()
{
    markupConverter = new MarkupConverter.MarkupConverter();
     html = markupConverter.ConvertRtfToHtml(rtf);
}
于 2013-04-24T15:05:13.730 回答
0
    using System.Threading; 

    Thread t = new Thread(new ThreadStart(ProcessRequest)); 

    // Make sure to set the apartment state BEFORE starting the thread. 
    t.ApartmentState = ApartmentState.STA; 
    t.Start(); 

    public void ProcessRequest(HttpContext context)
    {
       if (context.Request.Form.Count > 0)
       {
        string rtf = context.Request.Form[0];
        string html = "";
        if (rtf != "")
        {
           markupConverter = new MarkupConverter.MarkupConverter();
           html = markupConverter.ConvertRtfToHtml(rtf);
        }
        if (html != "")
        {
           context.Response.ContentType = "text/html";
           context.Response.Write(html);
        }
        else
        {
           context.Response.ContentType = "text/plain";
           context.Response.Write("Error from RTF2HTML");
        }
     }
  }
于 2013-04-24T15:03:26.230 回答