0

I'm developing a windows form application that reads a file line by line[In background worker thread] and populates a datagridview[using BeginInvoke]. While this is being done the UI becomes non responsive(Unable to Cancel/Exit or drag window) but I'm able see datagridview being updated. What i know is that this is due to the fact that messages are being pumped into message queue which have higher priority than user input messages.

Is there a way by which the UI can still remain responsive to User Input?

deXter
  • 354
  • 4
  • 21

2 Answers2

1

Since you are using BeginInvoke, you are doing things on the UI thread. If you read line by line and append each line one at a time, it doesn't really help having a background worker there.

You should rather add all at once, or at least in blocks, if there is some requirement to update the view while loading. Usually it's faster to just load and then add the data in one go.

Sami Kuhmonen
  • 30,146
  • 9
  • 61
  • 74
  • The data is pretty huge(50,000 + records) so the user should be able to see the progress as the data is being imported.Also the reading is done in the background thread,BeginInvoke is just being used to update the UI. – deXter Oct 28 '15 at 05:54
  • @deXter As Sami suggested, do so in blocks/batches rather than 1-by-1. Otherwise you'll just flood the Windows Message Pump for your app making everything slow down including paints and mouse. –  Oct 28 '15 at 06:01
  • @Micky If I send data from Background worker in chunks lets say of 100 records each. Won't it hang the UI thread while those 100 records are being populated into the datagridview. – deXter Oct 28 '15 at 06:33
  • @deXter It's much faster to tell the grid to stop updating, add 1000 records and say "ok, you can update" than one by one. – Sami Kuhmonen Oct 28 '15 at 06:34
  • 2
    @deXter Don't make the mistake of thinking that the call of `BeginInvoke` from the worker thread is actually updating the UI - it's not. It's notifying the UI thread to perform the operation on the worker's behalf. Non-STA worker threads can not update the UI –  Oct 28 '15 at 06:39
  • `BeginInvoke` executes the specified action asynchronously instead of blocking the UI thread. It adds the message to event queue of the Dispatcher to update the UI asynchronously. I concur with @Sami to update the grid in chunks instead of notifying for each record. – user1672994 Oct 28 '15 at 06:54
0

Try to Use Task Library rather than going with BackgroundWorker(Task is anytime better than BackgroundWorker) , below snippet can help

    CancellationTokenSource tokenSource2 = new CancellationTokenSource();
    CancellationToken ct;
    public MainWindowViewModel()
    {      

        ct = tokenSource2.Token;
        Task.Factory.StartNew(PopulateDataGrid, ct);
    }

    /// <summary>
    /// 
    /// </summary>
    private void PopulateDataGrid()
    {           
        for (int i = 1; i < 10000; i++)
        {
            if (!ct.IsCancellationRequested)
            {

                 ///Populate Your Control here                   
            }
            else
            {
                break;
            }
        }
    }

    public void OnCancelCLick()
    {
        tokenSource2.Cancel();
    }
}