How to update a list box by an asynchronous call?

c#, delegates

Solution

For Win Forms you'll need to use the Control's Invoke method:

Executes the specified delegate on the thread that owns the control's underlying window handle

The basic scenario is:

- Do the heavy lifting work with a BackgroundWorker to retrieve all of your items on a non UI blocking thread.

- On the BackgroundWorker.RunWorkerCompleted Event, use the Control's Invoke method to add the items to the Control (ListBox in your case).

Something along the lines of:

var bw = new BackgroundWorker();
bw.DoWork += (sender, args) => MethodToDoWork;
bw.RunWorkerCompleted += (sender, args) => MethodToUpdateControl;
bw.RunWorkerAsync();

This should get you going in the right direction.

Edit: working sample

public List<string> MyList { get; set; }

private void button1_Click( object sender, EventArgs e )
{
    MyList = new List<string>();

    var bw = new BackgroundWorker();
    bw.DoWork += ( o, args ) => MethodToDoWork();
    bw.RunWorkerCompleted += ( o, args ) => MethodToUpdateControl();
    bw.RunWorkerAsync();
}

private void MethodToDoWork()
{
    for( int i = 0; i < 10; i++ )
    {
        MyList.Add( string.Format( "item {0}", i ) );
        System.Threading.Thread.Sleep( 100 );
    }
}

private void MethodToUpdateControl()
{
    // since the BackgroundWorker is designed to use
    // the form's UI thread on the RunWorkerCompleted
    // event, you should just be able to add the items
    // to the list box:
    listBox1.Items.AddRange( MyList.ToArray() );

    // the above should not block the UI, if it does
    // due to some other code, then use the ListBox's
    // Invoke method:
    // listBox1.Invoke( new Action( () => listBox1.Items.AddRange( MyList.ToArray() ) ) );
}

Problem

I have developed a windows forms c# application, i just want update items in a Listbox in the main form by spin offing another thread without blocking the GUI form. Since threads cannot access form entities like listbox, i thought of using delegates. Following code in the below shows how i used a delegate to do that task, but it blocks the GUI form. so i just want to convert it to an asynchronous delegate which updates list box without blocking the GUI Form delegate declaration ``` delegate void monitoringServiceDel(); ``` calling the delegate ``` new monitoringServiceDel(monitoringService).BeginInvoke(null, null); ``` delegate method implementation ``` private void monitoringService() { this.listEvents.Invoke(new MethodInvoker(delegate() { int i = 0 ; while (i<50) { listEvents.Items.Add("count :" + count++); Thread.Sleep(1000); i ++; } })); } ```

Original source