CreateCollection() and threading

54 views
Skip to first unread message

Michel van den Berg

unread,
May 8, 2013, 10:39:15 AM5/8/13
to reacti...@googlegroups.com
Hi there,

I have a ViewModel with the following collection:

public ReactiveCollection<TeamProject> Projects { get; set; }

This collection is loaded using:

var teamProjects = _planService.TeamProjects();
Projects = teamProjects.CreateCollection();

whereas...

public IObservable<TeamProject> TeamProjects()
{
    return _teamProjectRepository.GetProjects().ToObservable();
}

and...

public IEnumerable<TeamProject> GetProjects()
{
    // iterations with a yield after loading the teamProject in a time-consuming webservice call
    yield return teamProject;
}

So basically, I'm converting an IEnumerable<TeamProject> to an IObservable<TeamProject> to a ReactiveCollection<TeamProject>
This loads fine, but it blocks my UI. While searching on the internet why this blocks, I've found that I probably should (please correct me if I'm wrong) add a schedular to the ToObservable() method.

So I changed it to use .ToObservable(Scheduler.Default)

The UI doesn't block anymore, but when the collection receives items, I get a threading exception:
"This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread."

From what I understand, CreateCollection() should synchronize the threads, not?


Michel van den Berg

unread,
May 8, 2013, 10:53:32 AM5/8/13
to reacti...@googlegroups.com
Btw... 

teamProjects.ObserveOn(SynchronizationContext.Current).Subscribe(x =>
{
    Projects.Add(x);                                
});

... does work. I thought CreateCollection() would be similar.

Paul Betts

unread,
May 8, 2013, 1:31:32 PM5/8/13
to reacti...@googlegroups.com
Hi Michel,

> From what I understand, CreateCollection() should synchronize the threads,
> not?

I think that the core issue is the way that you're loading projects

> public IEnumerable<TeamProject> GetProjects()

This is fundamentally a blocking construct, yet it's from a web call. Let's
model it a different way:

public IObservable<List<TeamProject>> GetProjects();

You could read this return type as "A Future of List of TeamProjects". Then,
we can project this to Projects easily:

LoadProjects = new ReactiveAsyncCommand();

LoadProjects.RegisterAsyncObservable(() => GetProjects())
.ToProperty(this, x => x.Projects);

--
Paul Betts <pa...@paulbetts.org>
> --
> You received this message because you are subscribed to the Google Groups "ReactiveUI mailing list" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to reactivexaml...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

IanYates

unread,
May 8, 2013, 7:31:28 PM5/8/13
to ReactiveUI mailing list
Hi Michel / Paul,

I may be reading between the lines a little too much, but I assume
you've modelled things that way because there's a web service call for
each TeamProject, and you want them to appear in the UI to the user as
they're loaded rather than appearing to the user in one big bang (the
"future list").

In that case your follow-up post seems ok to me although there's
possibly a better way to do it (I'm still finding all the handy things
that are in ReactiveUI). I myself need to code something similar
later today (it'll probably drift into tomorrow) so if I think of a
better way I'll come back here to post.

On May 9, 3:31 am, Paul Betts <paul.be...@gmail.com> wrote:
> Hi Michel,
>
> > From what I understand, CreateCollection() should synchronize the threads,
> > not?
>
> I think that the core issue is the way that you're loading projects
>
> > public IEnumerable<TeamProject> GetProjects()
>
> This is fundamentally a blocking construct, yet it's from a web call. Let's
> model it a different way:
>
> public IObservable<List<TeamProject>> GetProjects();
>
> You could read this return type as "A Future of List of TeamProjects". Then,
> we can project this to Projects easily:
>
> LoadProjects = new ReactiveAsyncCommand();
>
> LoadProjects.RegisterAsyncObservable(() => GetProjects())
>     .ToProperty(this, x => x.Projects);
>
> --
> Paul Betts <p...@paulbetts.org>
Reply all
Reply to author
Forward
0 new messages