在单独的线程上加载WPF Combobox

时间:2014-06-04 19:29:51

标签: c# wpf wpf-controls

我正在尝试使用数据库中的表加载这个组合框,一切正常,但它有很多记录,加载需要一分钟。我想把它移到一个单独的线程,但我一直在进行交叉线程。我认为交叉线程正在发生b / c组合框在ui线程上。有没有人知道实现这一目标的简单方法。

谢谢迈克尔

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;
}

2 个答案:

答案 0 :(得分:0)

试试这个:

 Dispatcher.Invoke(new Action(() =>
    {
        // Your combo items loading code here
    }));

答案 1 :(得分:0)

我将提及可能的解决方案

  1. Dispatcher.Invoke to sequential calling或Dispatcher.BeginInvoke for asynchronous
  2. 新主题

    var thread = new Thread(new ThreadStart(delegate{ code to update }));
    
  3. 这是不推荐的,因为它消耗了大量的时间和内存来创建一个线程,而不是使用这个

    ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
                    {
    
                    }));
    

    它创建线程,当它完成它的工作时它将它带回池,他的状态变为空闲,当新方法被添加到池中时,没有自动创建线程,但它从查找空闲线程然后唤醒开始他了不要在其中加入耗时的方法,因为它可能会导致一些线程正在运行而其他线程正在等待。

    3.另一种方法是BackgroundWorker。它使用SynchronizationContext在普通线程和UI线程之间切换。

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

    方法ProgressChanged和RunWorkerCompleted在UI线程上工作。 Backgroundworker顺便使用ThreadPool。线程设置为后台线程(这意味着当您关闭应用程序线程时也将关闭)。避免在UI线程上冻结线程。考虑不在开头加载所有内容,而是在列表框中向下滚动时逐渐加载。