2013-04-24 45 views
1

我試圖使用MSDN的Converting between RTF and HTML庫將一些RTF文本轉換爲HTML。我的設置的jist是從JavaScript到C#處理程序的AJAX調用,它調用此MarkupConverter庫進行轉換,然後寫回HTML。RichTextBox - InvalidOperationException:調用線程必須是STA

這裏是我的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:調用threa d必須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 document)+56
MarkupConverter.RtfToHtmlConv erter.ConvertRtfToXaml(字符串rtfText) +67 MarkupConverter.RtfToHtmlConverter.ConvertRtfToHtml(字符串rtfText)+23 MyHandler.ProcessRequest(HttpContext的背景下)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?如果是這樣的話,我如何設置回調函數來返回我目前使用的HTML Response.Write

回答

3

這可能是有用的:

How to run something in the STA thread?

也許你可以撥打電話,以...

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); 
} 
+0

執行'thread.Join()'後會執行等待,以便在'ConvertMarkup()'完成後'if(html!='')'行不執行? – lhan 2013-04-24 15:13:10

+0

顯然它!工作!謝謝! – lhan 2013-04-24 15:15:53

+2

沒問題,樂於幫忙! thread.Join自己發信號給調用線程等待,直到線程執行完成...簡單但是完成工作。 – Henners 2013-04-24 15:24:28

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"); 
     } 
    } 
    } 
+0

雖然,很明顯這將創建一個新的線程,但沒有辦法繞過它。有很多谷歌搜索,你可以做,看看爲什麼這是需要用戶界面。 – Jeff 2013-04-24 15:04:42

+0

謝謝。一個問題 - 新的ThreadStart行上的語法錯誤,「ProcessRequest的重載沒有匹配委託」System.Threading.ThreadStart「」。有任何想法嗎? – lhan 2013-04-24 15:06:31

+0

是的......對不起我的壞處。爲你的函數鬆開HttpContext參數。你不能傳遞函數一個參數。 – Jeff 2013-04-24 15:16:30

相關問題