微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

UnauthorizedAccessException:Silverlight应用程序(XAML / C#)中的跨线程访问无效

相对较新的C#,并想尝试玩一些第三方Web服务API与它.

这是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#中处理这些类型的交互的正常流程是什么?

谢谢.

解决方法

通过CheckAccess调用获取简单的交叉线程访问的一个有用的方法是在静态类中包装一个实用程序方法.

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的调用包装在背景线程上,如下所示:

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");
}

这样你不必知道你是否处于后台线程,并且避免了向每个控件添加方法来检查这一点的开销.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐