我从数据库中获取数据,并根据父comboBox值将其同时绑定到3个不同的组合框。以下是示例,我有三个名为
的组合框i. comboBoxBranch
ii. comboBoxClass
iii. comboBoxSection
comboBoxClass的值是在所选分支的基础上从数据库中获取的,同样,comboBoxSection的值是在所选分支和所选类的基础上获取的。所以绑定的顺序是(ComboBoxBranch)然后是comboBoxClass,然后是comboBoxSection。
现在为了实现这一点,我使用单独的线程来调用GetBranches()方法,以下面的方式将数据与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和comboBoxSection的其他两个组合框绑定,我应该使用另一个线程,因为我正在使用Getbranch方法,或者有任何其他干净的方法来实现这一点。以下是我在comboBoxBranches的comboBoxBranches_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";
});
}
}
相同的方法是comboxBoxSections,其值基于ComboBoxBranches和comboBoxClasses?我是多线程的新手。
答案 0 :(得分:2)
调用意味着等待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#将等待任务之后的行(带有comboBoxClasses
的3行)放入回调方法中。
如Async in depth (Microsoft)中所述,您还应该重写GetClasses
以异步工作并返回Task<T>
对象,而不是在此处启动新线程。
var classes = await _schoolManagementSystemServiceClient.GetClassesAsync(branch.BranchId);