C# 使ComboBox数据源集加载异步
我想用50000个项目填充一个组合框 问题是。。。将所有项目加载到GUI中需要花费太多时间 所以我尝试填充Asynchronous: 首先,我创建数据源数组:C# 使ComboBox数据源集加载异步,c#,winforms,performance,asynchronous,combobox,C#,Winforms,Performance,Asynchronous,Combobox,我想用50000个项目填充一个组合框 问题是。。。将所有项目加载到GUI中需要花费太多时间 所以我尝试填充Asynchronous: 首先,我创建数据源数组: var source = Enumerable.Range(1, 50000).Select(e => new{ID = e}).ToArray(); 然后设置组合框的datasource属性: BeginInvoke(new Action(() => comboBox1.DataSource = source));
var source = Enumerable.Range(1, 50000).Select(e => new{ID = e}).ToArray();
然后设置组合框的datasource属性:
BeginInvoke(new Action(() => comboBox1.DataSource = source));
上述代码行的问题需要花费大量时间才能完成,并且窗口冻结
我使用的解决方法是将数据源设置为null,并在foreach语句中添加该项,每次调用Application.DoEvents():
comboBox1.DataSource = null;
foreach (var e in source)
{
comboBox1.Items.Add(e);
Application.DoEvents();
}
它工作得很好,但是我需要将comboBox与数据源绑定,这样我就不能
如何设置数据源并使其像上面的代码那样加载?带有100项的组合框是个坏主意,但如果您坚持填充5000项 获取好的老
backgroundworker
并将其连接起来以加载数据源,不管它是哪个对象,比方说一个数组。在伪代码中(这些方法可能有参数)
我不确定这对您的情况是否有帮助,但如果您正在设置DisplayMember和ValueMember,请确保始终将DataSource设置为最后一个。 这有很大的不同。
此处的详细信息:
我正试图用50000项填充组合框。
这听起来是个非常糟糕的主意,无论是从用户体验还是从用户界面性能来看。@EricJ。我知道,但是用户现在需要这种方式。实际上是5.000项,但出于测试目的,我正在使用50.000项来查看异步方式是否真正起作用您是否尝试将虚拟化设置到您的UI控件?滚动时会有点痛,但当绑定完全超出UI范围的数据时,UI不需要执行任何操作。即使是5000个项目,无论在性能还是可用性方面都很糟糕。事实上,你为了让它发挥作用而跳出了障碍,这应该表明你走错了路@cscmh99的想法是正确的。@cscmh99我使用winforms,我不知道如何使用组合框来实现这一点。有办法吗?谢谢你的回答,但是数组创建很快,问题是设置数据源。这是慢的部分…->cbo.DataSource=myArrayOfValues@乔治:那么答案是这样的。在BG线程上设置数据源,表单将保持响应。或者你说上面的代码冻结了表单?是的,因为cbo.DataSource=myArrayOfValues在主线程中运行,即使我输入dowork,它也会抛出交叉线程异常。而cbo.Invoke不能解决这个问题,因为设置发生在主线程中,而没有调用application.doeventsinternaly@George然后,有一些东西将不会冻结你的形式。检查更新。这将没有数据源,但它将添加您的项目而不冻结。是的,您不想在doWork
上设置combo,因为该方法运行在不同的线程上。这就是为什么您有已完成的工作
和进度
。因此,您可能必须放弃datasource属性以加载async而不是冻结HI T.S,但这正是我不想要的,我需要绑定组合。。。在我的问题中,我已经用application.doevents做了foreach add。。。这不会冻结我的窗口…但我确实需要数据源:(
void DoWork() // handles loading of an array
{
// load array here. cbo is disabled
myArrayOfValues = <whatever you get from DB>
foreach var item in myArrayOfValues
{
// here call `worker.Progress` and pass your item in argument
}
}
void OnWorkComleted(....)
{
// Set your combo as disabled initially, so people can't click while it is loading
cbo.Enabled = true;
}
void OnWorkerProgress(....)
{
// Add items one by one
cbo.Items.Add(myValue);
}
class Itm
{
string A {get; set;}
string B {get; set;}
string C {get; set;}
}
void Setup()
{
for (int i = 1; i < 4; i++)
{
cbo.Items.Add(new itm { a = "A" + i, b = "B" + i, c = "C" + i});
}
cbo.DisplayMember = "A";
cbo.ValueMember = "B";
}
void OnSelectedIndexChanged(....)
{
if (cbo.SelectedIndex > -1)
{
var item = (itm)cbo.SelectedItem;
MessageBox.Show(string.Format("Selected: {0}, {1}, {2}", item.A, item.B, item.C));
}
}