исключение несанкционированного доступа для «MessageBox» в SilverLight - PullRequest
1 голос
/ 21 сентября 2010

У меня есть этот кусок кода в моем проекте 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, которая не может выполнять такие действия.

Можете ли вы помочь мне?

Спасибо,

С уважением

1 Ответ

4 голосов
/ 21 сентября 2010

Я думаю, это потому, что определенные части Silverlight не могут быть вызваны кодом и должны исходить из пользовательского ввода;Я думаю, что MessageBox попадает в эту категорию.Поэтому, если MessageBox не вызывается в результате нажатия пользователем кнопки или гиперссылки, он не будет работать.

Обратите внимание, что он не должен быть в обработчике события нажатия кнопки или гиперссылки;где-нибудь дальше вниз по иерархии вызовов работает.Что я в основном делал, когда мне нужно было инициировать такие действия в результате асинхронного вызова службы, например, я вывел на экран ChildWindow, содержащую гиперссылку с надписью «нажмите здесь, чтобы открыть свой х» или что-то, что пользователь пытался сделать (якажется, я использовал его, чтобы открыть сгенерированный сервером PDF или подобный файл).

Кроме того, если MessageBox действительно может быть вызван без всего того, о чем я только что написал, то исключение межпотокового доступа можно решить с помощьювызов Dispatcher.Invoke или Dispatcher.BeginInvoke с передачей делегата, выполняющего фактическое действие.Это связано с тем, что асинхронные действия (очевидно) выполняются в отдельном потоке, но Silverlight, подобно WPF и аналогичным им WinForms, требуется доступ к своим элементам управления только из одного потока;вызов с использованием диспетчера элемента управления делегирует действия правильному потоку.

Чтобы использовать решение BeginInvoke, попробуйте это вместо простого вызова MessageBox.Show:

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

Это предполагает, что код находится вуправляющий код позади (UserControl, Window, что угодно), поэтому свойство Dispatcher доступно.Вы можете использовать BeginInvoke вместо Invoke, если вы хотите, чтобы время пользовательского интерфейса корректно обновлялось, но обычно разница незаметна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...