Search code examples
c#wpfdatagrid

Add items to DataGrid in another thread


I'm trying to add items to a DataGrid using WPF in a way the UI doesn't freeze.

Background: I have a list of IP addresses. With these IP addresses further information should be determined, e.g. the ping. This means, I go through every item of the IP list, determine the data based on the IP and insert the result into a new list. The content of this new list should be displayed in the DataGrid.

Now it is like this, that there are about 4000 IPs. It is estimated that about 15 entries per second will be added to the DataGrid list. However, the list will only be displayed after ALL items from one list have been processed and added into the new list.

My goal is to make it look something like this: https://www.youtube.com/watch?v=xWC1GvfCI0I

Do you perhaps have an idea how to solve this best? This is the last way I tried it:

public void Get()
    {
        Task.Run(() =>
        {
            using (var client = new WebClient())
            {
                var ips = client.DownloadString("http://monitor.sacnr.com/list/masterlist.txt");

                using (var reader = new StringReader(ips))
                {
                    for (string ip = reader.ReadLine(); ip != null; ip = reader.ReadLine())
                    {
                        this.Servers.Add(this._sacnr.GetServerProperties(ip));
                    }
                }
            }
        });
    }

Thank you.


Solution

  • I did it this way now.

    I call my Method like this: Task.Factory.StartNew(() => this.Get());

    And then I use my method like this:

    public void Get()
    {
        var sacnr = new SacnrConnector();
    
        using (var client = new WebClient())
        {
            var ips = client.DownloadString("http://monitor.sacnr.com/list/masterlist.txt");
    
            using (var reader = new StringReader(ips))
            {
                for (string ip = reader.ReadLine(); ip != null; ip = reader.ReadLine())
                {
                    var server = sacnr.GetServerProperties(ip);
    
                    // Here I use BeginInvoke to add elements to my ObservableCollection
                    Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new ParameterizedThreadStart(AddItem), server);
                }
            }
        }
    }
    
    private void AddItem(object server)
    {
        this.Servers.Add((Server)server);
    }
    

    And it works!