“MessageBox”的未经授权的访问异常在银光
我的 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 函数无法执行此类操作。
你能帮助我吗?
谢谢,
问候
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)
{
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为这是因为 Silverlight 的某些部分无法通过代码调用,而必须源自用户输入;我认为 MessageBox 属于这一类。因此,除非用户按下按钮或超链接而调用 MessageBox,否则它不会工作。
请注意,它不必位于按钮或超链接单击事件的处理程序中;调用层次结构下方的任何地方都可以工作。例如,当我需要因异步服务调用而启动此类操作时,我基本上所做的是显示一个 ChildWindow,其中包含一个超链接,其中显示“单击此处打开您的 x”或用户尝试执行的任何操作(我我想我用它来打开服务器生成的 PDF 或类似文件)。
另外,如果 MessageBox 确实可以在没有我刚刚写的所有胡言乱语的情况下调用,则可以通过调用 Dispatcher.Invoke 或 Dispatcher.BeginInvoke 传递执行实际操作的委托来解决跨线程访问异常。这是因为异步操作(显然)发生在单独的线程中,但 Silverlight 与 WPF 和之前的 WinForms 一样,只需要从一个线程访问其控件;使用控件的调度程序调用会将操作委托给正确的线程。
要使用 BeginInvoke 解决方案,请尝试此操作,而不是简单地调用 MessageBox.Show:
假设代码位于 Control 代码隐藏中(UserControl、Window,任何内容),因此 Dispatcher 属性可用。如果您想让用户界面有时间正确地自行更新,则可以使用 BeginInvoke 而不是 Invoke,但通常差异是难以察觉的。
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:
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.