C# 如何在一个线程中调用多个控件?

C# 如何在一个线程中调用多个控件?,c#,multithreading,C#,Multithreading,我从数据库中获取数据,并根据父组合框值将其同时绑定到3个不同的组合框。下面是一个示例,我有三个组合框,名为 i. comboBoxBranch ii. comboBoxClass iii. comboBoxSection comboBoxClass的值是基于所选分支从数据库中获取的,类似地,ComboxSection的值也是基于所选分支和所选类获取的。所以绑定的顺序是(ComboBoxBranch),然后是comboBoxClass,然后是comboBoxSection 现在为了实现这一点,我

我从数据库中获取数据,并根据父组合框值将其同时绑定到3个不同的组合框。下面是一个示例,我有三个组合框,名为

i. comboBoxBranch
ii. comboBoxClass
iii. comboBoxSection
comboBoxClass的值是基于所选分支从数据库中获取的,类似地,ComboxSection的值也是基于所选分支和所选类获取的。所以绑定的顺序是(ComboBoxBranch),然后是comboBoxClass,然后是comboBoxSection

现在为了实现这一点,我使用separate线程调用getBranchs()方法,以下面的方式将数据绑定到comboboxBranch

    private void GetBranches() (This is working perfectly fine)
    {     
        if (comboBoxBranches.InvokeRequired)
        {
            comboBoxBranches.BeginInvoke(((MethodInvoker) delegate
            {
                comboBoxBranches.DataSource = _schoolManagementSystemServiceClient.GetBranches();
                comboBoxBranches.ValueMember = "BranchId";
                comboBoxBranches.DisplayMember = "BranchName";

            }));
        }  
现在问题出现了,我应该如何将数据绑定到其他两个comboxClass和ComboxSection组合框中,我应该使用另一个线程,就像我在Getbranch方法中使用的那样,或者有任何其他干净的方法来实现这一点。下面是我在ComboboxBranchs的事件方法ComboboxBranchs_SelectedValueChanged()中调用的GetClasses方法

private void comboBoxBranches_SelectedValueChanged(object sender, EventArgs e)
     {
         Thread thread=new Thread(GetClasses());
         thread.start();  
     }
 private void GetClasses()// in this method how should I achieve invoking  for multiple controls? What should I do here?
    {
           if (InvokeRequired)
        {
            comboBoxBranches.BeginInvoke(((MethodInvoker) delegate
            {
                Branch branch = comboBoxBranches.SelectedItem as Branch;
            }));
            comboBoxClasses.BeginInvoke((MethodInvoker) delegate
            {
                comboBoxClasses.DataSource = _schoolManagementSystemServiceClient.GetClasses(branch.BranchId);
                comboBoxClasses.ValueMember = "ClassId";
                comboBoxClasses.DisplayMember = "ClassName";
            });              
        }
    }

对于值同时基于ComboboxBranchs和ComboboxClass的comboxBoxSections,使用相同的方法?我不熟悉多线程。

调用意味着等待UI线程空闲,然后切换到UI线程并执行一些操作。因此,长时间运行的任务(例如,从数据库查询数据)必须在调用之前执行

今天,实现这一点的首选方法是使用async/await

private async void comboBoxBranches_SelectedValueChanged(object sender, EventArgs e)
{
    //  We are in the UI thread and can access the controls directly.
    Branch branch = comboBoxBranches.SelectedItem as Branch;

    var classes = await Task.Run(
        // This runs in a new thread. At this point the UI is not blocked.
        () => _schoolManagementSystemServiceClient.GetClasses(branch.BranchId)
    );
    // Here the thread joins the UI thread and returns the classes.

    // We are in the UI thread again. No need for Invoke.
    comboBoxClasses.DataSource = classes;
    comboBoxClasses.ValueMember = "ClassId";
    comboBoxClasses.DisplayMember = "ClassName";
}
注意方法标题中的关键字
async
。它告诉C#以一种特殊的方式处理此方法。在幕后,C#完全重写了这种方法,以实现神奇的效果,并隐藏了其中的复杂性

要理解这是如何工作的,可以想象C将等待的任务后面的行(带有
ComboboxClass
的3行)放入回调方法

如中所述,您还应该重写
GetClasses
以异步工作并返回
Task
对象,而不是在此处启动新线程

var classes = await _schoolManagementSystemServiceClient.GetClassesAsync(branch.BranchId);

请参阅:。

使用单独的线程需要什么?完全不需要单独的线程来加载3个组合框。只需按顺序调用asych并创建一个加载它们的事件Async@MohamedNajiullah我使用单独的线程,因为在加载组合框时,主UI会被卡住一段时间。我希望我的申请是有反应的。谢谢你的回答。但我试图实现的是使我的应用程序具有响应性,我已经应用了你在回答中提到的方法,但我的主UI仍然会被卡住一段时间,然后在组合框完全加载后变得响应。你能告诉我怎样才能使它响应迅速,这样我的主界面就不会被卡住。对你的方法进行计时,以了解时间在哪里流失(例如,使用a)。async/await对I/O操作有帮助,但对UI操作本身没有帮助。这些不能在其他线程中运行。