开发者

unauthorizedaccessexception for a "MessageBox" in SilverLight

开发者 https://www.devze.com 2023-01-17 12:42 出处:网络
I have this piece of code in my Silverlight project: private void button1_Click(object sender, RoutedEventArgs e)

I have this piece of code in my Silverlight project:

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)
{
 开发者_StackOverflow   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);
    }
}

When I run the code, I get the following exception:

unauthorizedaccessexception
Invalid cross-thread access.

I thought It was a problem with the returned string. But, even if I put this:

MessageBox.Show("foobar");

the same exception rises. I think that the problem comes from the ReadCallback function that cannot perform such actions.

Can you help me?

Thank you,

Regards


I think this is because certain parts of Silverlight cannot be invoked by code and instead must originate from user input; I think the MessageBox falls in this category. So unless the MessageBox is called as a result of the user pressing a button or hyperlink, it's not going to work.

Note that it doesn't have to be in the handler for the button or hyperlink click event; anywhere further down the call hierarchy works. What I basically did when I needed to initiate such actions as a result of an async service call, for instance, is I dispalyed a ChildWindow containing a hyperlink saying 'click here to open your x' or whatever the user was trying to do (I think I used it to open a server-generated PDF or similar file).

Also, if the MessageBox can indeed be called without all he malarkey I just wrote about, the Cross-thread access exception can be solved with a call to Dispatcher.Invoke or Dispatcher.BeginInvoke passing a delegate that does the actual action. That's because asynchronous actions (obviously) take place in a separate thread, but Silverlight, like WPF and like WinForms before them, needs to access its controls from only one thread; invoking using the control's Dispatcher delegates the actions to the correct thread.

To use the BeginInvoke solution, try this instead of simply calling MessageBox.Show:

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

That's assuming the code is in a Control code-behind (UserControl, Window, anything), so the Dispatcher property is available. You can use BeginInvoke instead of Invoke if you want to allow the user interface time to properly update itself, but usually the difference is imperceptible.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号