Load an ObservableCollection with a Task

2019-05-14 05:07发布

问题:

I am trying to load all the users in our active directory and display them in a ListBox. However if I do this like normal I freeze the UI thread for a long time. So is there anyway I can use a task to fill this collection up on a background thread while still getting the listbox to update as I insert new names?

回答1:

As you cannot load all the data in a separate thread (or task, whatever) and then fill the ObservableCollection, you can pass the current Dispatcher to the operation and use its InvokeAsync method to add the elements one by one to the Observable collection in the UI thread. Something like this:

public void FetchAndLoad()
    {
        // Called from the UI, run in the ThreadPool
        Task.Factory.StartNew( () =>
        this.FetchAsync(e => this.Dispatcher.InvokeAsync(
            () => this.observableCollection.Add(e)
            )
        ));
    }

    public void Fetch(Action<string> addDelegate)
    {
                    // Dummy operation
        var list = new List<string>("Element1", "Element2");

        foreach (var item in list)
            addDelegate(item);
    }

I would do that in batches, though, depending on the number of elements.