简体   繁体   中英

How to make a listview update in real time in C#

I have an app that crawls a network looking for movies, their titles, length and last accessed time. Since there are a lot of computers on the network, this can take awhile and I would like to update my listview in real time. Heres what I have so far but its not working at all.

        private void PopulateListView()
    {
        this.listView1.SuspendLayout();

        listView1.Items.Clear(); 

        // go thru list of movies to add
        foreach (string movie in listviewMovieList)
        {
            ListViewItem item1 = new ListViewItem(movie);
            listView1.Items.AddRange(new ListViewItem[] { item1 });

        }
        this.listView1.ResumeLayout();            
    }

This gets called by my background workers ProgressChanged method:

        private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        string movie = (string)e.UserState;            

        if (movie != null)
        {
            listviewMovieList.Add(movie);
            PopulateListView();

        }

        this.progressBar1.Increment(e.ProgressPercentage);            
    }

The problem is that it isn't slow enough. You are calling ReportProgress() too often. It depends on how much work the UI thread does, but do it roughly several hundred times per second and the UI thread freezes, not getting around do doing its normal duties anymore. Like painting the list view. Your code is very expensive, clearing and repopulating the ListView requires lots of Windows messages.

At least don't do it for one movie at a time, batch it up and use the AddRange() method. One call per 50 msec is ideal, a human cannot read any faster than that anyway. Slow down the worker thread by using Invoke() instead of BeginInvoke(). ListView.VirtualMode can help.

I think the issue might be to cross thread calls to WinForm UI controls.

Take a look at

Control.InvokeRequired Property

Gets a value indicating whether the caller must call an invoke method when making method calls to the control because the caller is on a different thread than the one the control was created on.

and Control.BeginInvoke Method (Delegate)

Executes the specified delegate asynchronously on the thread that the control's underlying handle was created on.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM