0

I'm trying to load this combobox with a table from the database, everything works fine but it is a lot of records and it takes a minute to load. I would like to move this to a separate Thread, but I keep getting cross threading. I think the cross threading is happening b/c the combobox is on the ui thread. Does anyone know a simple way to achieve this.

Thanks Michael

private void BindComboBox()
{
        SqlConnection con = Program.GetConnection;
        SqlDataAdapter da = new SqlDataAdapter("SELECT ContactId, FullName FROM dbo.Contact WHERE FULLNAME IS NOT NULL", con);
        DataSet ds = new DataSet();
        da.Fill(ds, "dbo.Contact");

        SearchBOX.ItemsSource =  ds.Tables[0].DefaultView;
        SearchBOX.DisplayMemberPath = ds.Tables[0].Columns["FullName"].ToString();
        SearchBOX.SelectedValuePath = ds.Tables[0].Columns["ContactId"].ToString();
        SearchBOX.IsEnabled = true;
}
perirose
  • 54
  • 1
  • 10
  • 1
    Use Dispatcher.BeginInvoke around the UI operations. Even better, just bind the ItemsSource and update the backing property in your new thread. – BradleyDotNET Jun 04 '14 at 19:30
  • Can use a background worker to load the data on another thread. Then you bind the data to the UI control in complete event. Only the main thread can access a UI control. So what is above the blank line you do on the backgroundoworker. – paparazzo Jun 04 '14 at 20:22
  • why not utilize one of the most powerful aspects of WPF - databinding? – mcy Jun 04 '14 at 21:59

2 Answers2

0

Try this one :

 Dispatcher.Invoke(new Action(() =>
    {
        // Your combo items loading code here
    }));
HichemSeeSharp
  • 3,240
  • 2
  • 22
  • 44
0

I will mention possible solutions

  1. Dispatcher.Invoke to sequential calling or Dispatcher.BeginInvoke for asynchronous
  2. New Thread by

    var thread = new Thread(new ThreadStart(delegate{ code to update }));
    

this is not recommended since it consumes a lot of time and memory to create a single thread, instead use this

ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
                {

                }));

it creates thread and when it finishes its work it brings him back to pool, his status is changed to idle and when new method is added to pool no thread is automatically created but it starts from looking for a idle thread and then wake him up. Do not put a time-consuming methods in it since it can turn out that couple threads are running and others are waiting idly.

3.Another way out is BackgroundWorker. It uses SynchronizationContext to switch between ordinary thread and UI thread.

        var worker = new BackgroundWorker();
        worker.DoWork += worker_DoWork;
        worker.WorkerReportsProgress = true;
        worker.ProgressChanged += worker_ProgressChanged;
        worker.RunWorkerCompleted += worker_RunWorkerCompleted;
        worker.RunWorkerAsync();

Method ProgressChanged and RunWorkerCompleted work on UI thread. Backgroundworker uses ThreadPool by the way. Threads are set to be Background Thread(which means that when you shut down app threads will be shut down as well). Avoid freezing thread on UI thread. Consider not loading everything at the beginning but gradually during scrolling down in listbox.

Maximus
  • 3,458
  • 3
  • 16
  • 27