2010-09-21 29 views
1

一個「MessageBox的」我有這樣的一段代碼在我的Silverlight項目:unauthorizedaccessexception用於在Silverlight

private void button1_Click(object sender, RoutedEventArgs e) 
{ 
    string baseUri = "http://foo.bar"; 
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(new Uri(baseUri)); 
    request.BeginGetResponse(new AsyncCallback(ReadCallback),request); 
} 
private void ReadCallback(IAsyncResult asynchronousResult) 
{ 
    HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; 
    HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult); 
    using (StreamReader streamReader1 = new StreamReader(response.GetResponseStream())) 
    { 
     string resultString = streamReader1.ReadToEnd(); 
     MessageBox.Show(resultString); 
    } 
} 

當我運行代碼,我得到以下異常:

unauthorizedaccessexception 
Invalid cross-thread access. 

我想這是返回的字符串的問題。但是,即使我把這個:

MessageBox.Show("foobar"); 

同樣的例外上升。 我認爲問題來自無法執行此類操作的ReadCallback函數。

你能幫我嗎?

謝謝

問候

回答

4

我想這是因爲Silverlight中的某些部分不能用代碼來調用,而是必須從用戶輸入的起源;我認爲MessageBox屬於這個類別。所以除非MessageBox被用戶按下按鈕或超鏈接的結果調用,否則它不會起作用。

請注意,它不必位於按鈕或超鏈接單擊事件的處理程序中;調用層次結構的任何位置都可以工作當我需要發起異步服務調用的結果時,我基本上做了什麼,例如,我展示了一個包含超鏈接的ChildWindow,它說'點擊這裏打開你的x'或用戶試圖做的任何事情(我認爲我用它來打開服務器生成的PDF或類似的文件)。另外,如果MessageBox確實可以在沒有他寫的所有malarkey的情況下被調用,那麼跨線程訪問異常可以通過調用Dispatcher.Invoke或Dispatcher.BeginInvoke來傳遞一個委託來完成,該委託執行實際的操作。這是因爲異步操作(顯然)發生在單獨的線程中,但像WPF之類的Silverlight和像之前的WinForms一樣,需要僅從一個線程訪問其控件;使用控件的Dispatcher調用將操作委託給正確的線程。

要使用的BeginInvoke解決方案,試試這個,而不是簡單地調用MessageBox.Show的:

string resultString = streamReader1.ReadToEnd(); 
Dispatcher.Invoke(new Action(() => MessageBox.Show(""))); 

這是假設的代碼是在控制代碼隱藏(用戶控件,窗口,任何東西),所以調度屬性可用。如果您想允許用戶界面時間正確更新自己,則可以使用BeginInvoke而不是Invoke,但通常不會發現差異。

+0

@Alex Paven:我想你錯過了實際的問題。 MessageBox是之後加入到跨線程問題的紅鯡魚。 – 2010-09-21 15:52:58

+0

是的,也立即更新我的答案,包括Dispatcher.Invoke,但我完全明白,我有一個複雜和冗長的風格,可能會觸發TLDR反應。 – 2010-09-21 16:02:59

+1

對於最後一段「Dispatcher.BeginInvoke」是+1。 – AnthonyWJones 2010-09-21 16:04:38

相關問題