2

J'essaie de mettre à jour mon interface utilisateur Silverlight 4 toutes les 1/2 secondes environ avec de nouvelles données. J'ai accroché dans un service WCF utilisant la liaison net.tcp et l'émission de rappels à partir du serveur. Pour m'assurer que je reçois les données du service le plus rapidement possible, j'ai démarré mon proxy sur un backround worker à l'intérieur de mon application Silverlight.Silverlight 4 Multithread

Ma question est, comment puis-je obtenir les résultats du rappel et mettre à jour le ObservableCollection qui est lié à un datagird? J'ai essayé un certain nombre de manières différentes et continue à obtenir l'erreur de croix-fil redoutée.

Répondre

3

Utilisez le DispatcherBeginInvoke. Par exemple: -

private void MyCallback(object sender, SomeArgsClass e) 
{ 
    // perhaps some extraction of a payload or something 
    Deployment.Current.Dispatcher.BeginInvoke(() => 
    { 
     // Code you need to run on the UI thread. 
    }); 

    // Note code may or may not exit here before code above has completed. 
    // So be careful with disposable types etc. 
} 
2

Il y a plusieurs approches que vous pouvez prendre:

  • utilisation Deployment.Current.Dispatcher du fil d'arrière-plan, et faire une Deployment.Current.Dispatcher.CheckAccess() appel à ce sujet

  • passe le répartiteur à partir du composant d'interface utilisateur qui lance le fil de fond, et de l'utilisation que la poignée pour effectuer le CheckAccess() appelC'est mon option préférée: passer un délégué (rappel) au thread d'arrière-plan, quand il a de nouvelles données qu'il appelle ce délégué, et ce délégué vit dans le contrôle de l'interface utilisateur - il peut alors utiliser le Dispatcher disponible sur le le contrôle de l'interface utilisateur

le modèle pour ce genre de chose est:

private void DoMyUIUpdate(List<object> updates) 
{ 
    if (Deployment.Current.Dispatcher.CheckAccess()) 
    { 
     //do my work, update the UI 
    } 
    else 
     Deployment.Current.Dispatcher.BeginInvoke(new Action<List<object>>(DoMyUIUpdate), updates); 
} 
+0

Si j'utilise l'option 3 (le préféré) je perds sur toutes les améliorations de performances que le démarrage du proxy sur le thread de travail gains, puisque les rappels seraient émis à l'interface utilisateur ré. Check this out: http://tomasz.janczuk.org/2010/03/comparison-of-http-polling-duplex-and.html – DavyMac23

+0

Non, vous n'avez pas - toute sorte de mise à jour de l'interface utilisateur doit être fait sur le Le thread d'interface utilisateur, invoquant n'importe quoi sur le Dispatcher signifie qu'il est rassemblé sur le thread UI. Le * // fait mon travail * pourrait être aussi simple que de mettre à jour la collection à laquelle votre interface utilisateur est liée. L'amélioration des performances dont vous parlez récupère les données d'une manière qui ne bloque pas le thread de l'interface utilisateur. La mise à jour de l'interface utilisateur n'est pas effectuée depuis le thread d'arrière-plan, quelle que soit la méthode utilisée pour Dispatcher. – slugster