Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在单独的线程上加载WPF Combobox_C#_Wpf_Wpf Controls - Fatal编程技术网

C# 在单独的线程上加载WPF Combobox

C# 在单独的线程上加载WPF Combobox,c#,wpf,wpf-controls,C#,Wpf,Wpf Controls,我正在尝试从数据库中加载这个组合框,其中包含一个表,一切正常,但它有很多记录,加载需要一分钟。我想把它转移到一个单独的线程,但我一直在使用交叉线程。我认为交叉线程正在b/c中发生,组合框在ui线程上。有人知道实现这一目标的简单方法吗 谢谢你,迈克尔 private void BindComboBox() { SqlConnection con = Program.GetConnection; SqlDataAdapter da = new SqlDataAdapt

我正在尝试从数据库中加载这个组合框,其中包含一个表,一切正常,但它有很多记录,加载需要一分钟。我想把它转移到一个单独的线程,但我一直在使用交叉线程。我认为交叉线程正在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;
}
试试这个:

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

我将提到可能的解决办法

  • Dispatcher.Invoke调用顺序调用或Dispatcher.BeginInvoke调用异步
  • 新线程

    var thread = new Thread(new ThreadStart(delegate{ code to update }));
    
  • 不建议这样做,因为创建单个线程会消耗大量时间和内存,请改用此方法

    ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
                    {
    
                    }));
    
    它创建线程,当它完成它的工作时,它将他带回池中,他的状态更改为空闲,当新方法添加到池中时,不会自动创建线程,但它会从寻找空闲线程开始,然后将他唤醒。不要在其中放入耗时的方法,因为结果可能是两个线程正在运行,而其他线程正在空闲地等待

    3.另一个出路是幕后工作者。它使用SynchronizationContext在普通线程和UI线程之间切换

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

    方法ProgressChanged和RunWorker已完成UI线程上的工作。顺便说一下,Backgroundworker使用ThreadPool。线程被设置为后台线程(这意味着当你关闭应用程序时,线程也将被关闭)。避免冻结UI线程上的线程。考虑不要在开始时加载所有的东西,但在ListBox中滚动时要逐渐地进行。

    使用Debug。更妙的是,只需绑定ItemsSource并更新新线程中的backing属性即可。天哪,感谢您,因为响应可以使用后台工作程序在另一个线程上加载数据。然后在完成事件中将数据绑定到UI控件。只有主线程才能访问UI控件。那么,你在BooBooWorkWORKE上做的空白行是什么?为什么不利用WPF-数据绑定的最强大的方面之一呢?