2010-08-06 5 views
12

Relativ neu zu C# und wollte versuchen, mit einigen Web-Service-APIs von Drittanbietern damit zu spielen. HierUnauthorizedAccessException: Ungültiger Cross-Thread-Zugriff in Silverlight-Anwendung (XAML/C#)

ist der XAML-Code

<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> 

und hier ist der C# -Code

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

Ich vermute, dass dies durch die Tatsache verursacht wird, dass der Rückruf auf einem separaten Thread ausgeführt wird als die UI? Was ist der normale Ablauf, um mit diesen Arten von Interaktionen in C# umzugehen?

Danke.

+0

Vielen Dank für Ihre Antworten. – PolandSpring

+0

Eine andere Möglichkeit, dies zu tun, ist die Verwendung des this.Dispatcher , aber dieser Link ist sehr hilfreich für Sie. http://humrahimcs.wordpress.com/wp-admin/post.php?post=420&action=edit&message=6&postpost=v2 – DoNetDeveloper

+0

Warum akzeptierst du Steve Willcocks Antwort nicht? –

Antwort

2

Eine andere Möglichkeit ist die Verwendung der this.Dispatcher.CheckAccess()-Funktion. Es ist das gleiche wie das, was Sie in WPF bekommen, aber es erscheint nicht in Ihrem Intellisense, so dass Sie es vielleicht nicht gesehen haben. Was Sie tun, ist zu überprüfen, ob Sie Zugriff auf den UI-Thread haben, und wenn Sie nicht rekursiv rufen Sie auf dem UI-Thread zurück.

Dies ist nur ein sehr einfaches Beispiel und kann nicht mehr verwaltet werden, sobald Sie mehr als ein paar Kontrollen haben. Für einige WPF/Silverlight-Sachen habe ich eine generische Funktion benutzt, die auch das UI-Steuerelement aktualisiert, ebenso wie das Update selbst. Auf diese Weise habe ich keine dieser Funktionen für jedes Steuerelement auf der Seite, die aktualisiert werden muss die Ergebnisse eines Hintergrundthreads.

29

Eine nützliche Möglichkeit, um einfachen Thread-Zugriff mit dem CheckAccess-Aufruf zu erhalten, besteht darin, eine Dienstprogrammmethode in einer statischen Klasse - z.

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

dann können Sie Anrufe wickeln, die die Benutzeroberfläche aktualisieren, wo Sie sich wie so auf einem Hintergrund-Thread sein kann:

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

Auf diese Weise müssen Sie nicht wissen, ob Sie auf einem Hintergrund sind thread oder nicht und es vermeidet den Overhead des Hinzufügens von Methoden zu jedem Steuerelement, um dies zu überprüfen.

+0

Dies funktioniert hervorragend für Windows Phone 7. großartige Lösung. – scottbates22

+0

Super! Genau das, was ich brauchte. –

Verwandte Themen