2013-07-03 3 views
2

J'essaye de réactiveui, et je ne comprends pas comment faire un simple scénario de travail: J'ai une méthode qui écoute les messages dans une salle de discussion. Ainsi, il est long et déclenche des événements lorsqu'un message est trouvé. En utilisant réactiveui, je veux lancer cette méthode de longue durée lorsque la fenêtre s'ouvre, et avoir de nouveaux messages remplis sur l'écran dans une liste. Parce que j'utilise rx, je suppose que je avais besoin d'une version IObseravble de la longue méthode de course, donc je fait un comme ceci:Comment s'inscrire à la source de messages à long terme

public static IObservable<Message> ObservableStream(int roomid, CancellationToken token) 
    { 
     return Observable.Create<Message>(
      async (IObserver<Message> observer) => 
       { 
       ... 
       } 
     ); 
    } 

Mais, Je ne sais pas comment cela en sondent reactiveui. Aurais-je besoin d'un ObservableAsPropertyHelper<List<Message>>? Pour le moment, je lance simplement la méthode longue durée dans un Task.Factory.Startnew, puis sur les événements que j'ajoute manuellement à une liste de messages, qui est liée à la zone de liste frontale. Cela fonctionne, mais il ne l'utilise tout reactiveui, et il me semble qu'il devrait y avoir un moyen reactiveui de le faire:

public class MainWindowViewModel : ReactiveObject 
{ 
    private ThreadSafeObservableCollection<Message> _Messages; 
    public ThreadSafeObservableCollection<Message> Messages 
    { 
     get { return _Messages; } 
     set { 
      this.RaiseAndSetIfChanged(x => x._Messages, value); 
     } 
    } 


    public MainWindowViewModel() 
    { 
     Client.NewMessage += (sender, args) => Messages.Add(args.Message); 
     var task = Task.Factory.StartNew(() => Client.GetStream(token), token, TaskCreationOptions.LongRunning, TaskScheduler.Current); 

    } 
} 


// IN the code-behind 

this.OneWayBind(ViewModel, x => x.Messages, x => x.MessageList.ItemsSource); 

Répondre

2

Que diriez-vous:

var Messages = ObservableStream(...).CreateCollection(); 

Ensuite, vous pouvez écouter les messages pour ItemAdded et al, ou simplement le lier via OneWayBind et l'interface utilisateur sera mise à jour automatiquement.

Aurais-je besoin d'un ObservableAsPropertyHelper>?

Donc, normalement ce serait une bonne idée pour la plupart des appels API Web, mais puisque vous le streaming la liste au lieu de remplaçant la liste à chaque fois, vous devez créer une collection au démarrage et ajouter des éléments à eux comme ils viennent po Une autre manière que vous pourriez faire ceci est:

var Messages = new ReactiveList<Message>(); 
ObservableStream(...).ObserveOn(RxApp.MainThreadScheduler).Subscribe(x => Message.Add(x)); 
+0

C'est grand, merci. Pouvez-vous me dire quel est l'avantage de 'ObserveOn (RxApp.MainThreadScheduler)', je ne sais pas comment je devrais utiliser le Scheduler dans votre lib ... –

+0

Parce que la source de vos messages provient de threads de fond (à cause de async x => ...), vous devez vous assurer que 'Message.Add' est appelé sur le thread de l'interface utilisateur (j'ai corrigé le code ci-dessus, CreateCollection le fait pour vous) –

Questions connexes