UnauthorizedAccessException:Silverlight 应用程序中的跨线程访问无效 (XAML/C#) [英] UnauthorizedAccessException: Invalid cross-thread access in Silverlight application (XAML/C#)
问题描述
对 C# 比较陌生,想尝试使用一些第三方网络服务 API.
Relatively new to C# and wanted to try playing around with some third party web service API's with it.
这是 XAML 代码
<Grid x:Name="ContentGrid" Grid.Row="1">
<StackPanel>
<Button Content="Load Data" Click="Button_Click" />
<TextBlock x:Name="TwitterPost" Text="Here I am"/>
</StackPanel>
</Grid>
这里是C#代码
private void Button_Click(object sender, RoutedEventArgs e)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://api.twitter.com/1/users/show/keykoo.xml");
request.Method = "GET";
request.BeginGetResponse(new AsyncCallback(twitterCallback), request);
}
private void twitterCallback(IAsyncResult result)
{
HttpWebRequest request = (HttpWebRequest)result.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
TextReader reader = new StreamReader(response.GetResponseStream());
string strResponse = reader.ReadToEnd();
Console.WriteLine("I am done here");
TwitterPost.Text = "hello there";
}
我猜这是因为回调是在与 UI 不同的线程上执行的?在 C# 中处理这些类型的交互的正常流程是什么?
I'm guessing that this is caused by the fact that the callback executes on a separate thread than the UI? What is the normal flow to deal with these types of interactions in C#?
谢谢.
推荐答案
通过 CheckAccess 调用获得轻松跨线程访问的一种有用方法是将实用程序方法包装在静态类中 - 例如
A useful way to get easy cross thread access with the CheckAccess call is to wrap up a utility method in a static class - e.g.
public static class UIThread
{
private static readonly Dispatcher Dispatcher;
static UIThread()
{
// Store a reference to the current Dispatcher once per application
Dispatcher = Deployment.Current.Dispatcher;
}
/// <summary>
/// Invokes the given action on the UI thread - if the current thread is the UI thread this will just invoke the action directly on
/// the current thread so it can be safely called without the calling method being aware of which thread it is on.
/// </summary>
public static void Invoke(Action action)
{
if (Dispatcher.CheckAccess())
action.Invoke();
else
Dispatcher.BeginInvoke(action);
}
}
然后您可以将任何更新 UI 的调用包装在您可能在后台线程上的位置,如下所示:
then you can wrap any calls that update the UI where you may be on a background thread like so:
private void twitterCallback(IAsyncResult result)
{
HttpWebRequest request = (HttpWebRequest)result.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
TextReader reader = new StreamReader(response.GetResponseStream());
string strResponse = reader.ReadToEnd();
UIThread.Invoke(() => TwitterPost.Text = "hello there");
}
这样您就不必知道您是否在后台线程上,并且避免了向每个控件添加方法来检查这一点的开销.
This way you don't have to know whether you are on a background thread or not and it avoids the overhead of adding methods to every control to check this.
这篇关于UnauthorizedAccessException:Silverlight 应用程序中的跨线程访问无效 (XAML/C#)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!