C# 异步填充ASP.NET ListBox而不阻塞UI
我在ASP.NET用户控件中有一个列表框,我想用从数据库检索到的潜在较大的C# 异步填充ASP.NET ListBox而不阻塞UI,c#,asp.net,multithreading,.net-3.5,backgroundworker,C#,Asp.net,Multithreading,.net 3.5,Backgroundworker,我在ASP.NET用户控件中有一个列表框,我想用从数据库检索到的潜在较大的列表来填充该列表框(最多50k个项目)。由于正在填充列表框(在页面加载事件中),我不想阻止UI。使用同步代码,直到列表框填充完成后,才会显示页面: List<string> items = GetItemsFromDB(); foreach (var item in items) // can take some time, blocks UI { if (shouldItemBeListed(
列表来填充该列表框(最多50k个项目)。由于正在填充列表框(在页面加载事件中),我不想阻止UI。使用同步代码,直到列表框填充完成后,才会显示页面:
List<string> items = GetItemsFromDB();
foreach (var item in items) // can take some time, blocks UI
{
if (shouldItemBeListed(item))
ListBox1.Items.Add(item);
}
2。BackgroundWorker线程。比1工作得更好。(至少列表框正在更新新项目),但仍然反应迟钝
var bw = new BackgroundWorker();
bw.DoWork += (o, args) => Populate();
bw.RunWorkerAsync();
我总是可以将列表框项目分成更小的组,并根据用户的请求填充更多的内容,但这通常是如何正确实现的呢?Damon说得对,您正在寻找ajax,这应该会为您提供所需的功能。我发现了一个使用gridview的frmo MSDN示例,但它应该是可适应的:
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Collections.Generic" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Enter New Employees</title>
<script runat="server">
private List<Employee> EmployeeList;
protected void Page_Load()
{
if (!IsPostBack)
{
EmployeeList = new List<Employee>();
EmployeeList.Add(new Employee(1, "Jump", "Dan"));
EmployeeList.Add(new Employee(2, "Kirwan", "Yvette"));
ViewState["EmployeeList"] = EmployeeList;
}
else
EmployeeList = (List<Employee>)ViewState["EmployeeList"];
EmployeesGridView.DataSource = EmployeeList;
EmployeesGridView.DataBind();
}
protected void InsertButton_Click(object sender, EventArgs e)
{
if (String.IsNullOrEmpty(FirstNameTextBox.Text) ||
String.IsNullOrEmpty(LastNameTextBox.Text)) { return; }
int employeeID = EmployeeList[EmployeeList.Count-1].EmployeeID + 1;
string lastName = Server.HtmlEncode(FirstNameTextBox.Text);
string firstName = Server.HtmlEncode(LastNameTextBox.Text);
FirstNameTextBox.Text = String.Empty;
LastNameTextBox.Text = String.Empty;
EmployeeList.Add(new Employee(employeeID, lastName, firstName));
ViewState["EmployeeList"] = EmployeeList;
EmployeesGridView.DataBind();
EmployeesGridView.PageIndex = EmployeesGridView.PageCount;
}
protected void CancelButton_Click(object sender, EventArgs e)
{
FirstNameTextBox.Text = String.Empty;
LastNameTextBox.Text = String.Empty;
}
[Serializable]
public class Employee
{
private int _employeeID;
private string _lastName;
private string _firstName;
public int EmployeeID
{
get { return _employeeID; }
}
public string LastName
{
get { return _lastName; }
}
public string FirstName
{
get { return _firstName; }
}
public Employee(int employeeID, string lastName, string firstName)
{
_employeeID = employeeID;
_lastName = lastName;
_firstName = firstName;
}
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
</div>
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true" />
<table>
<tr>
<td style="height: 206px" valign="top">
<asp:UpdatePanel ID="InsertEmployeeUpdatePanel" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<table cellpadding="2" border="0" style="background- color:#7C6F57">
<tr>
<td><asp:Label ID="FirstNameLabel" runat="server" AssociatedControlID="FirstNameTextBox"
Text="First Name" ForeColor="White" /></td>
<td><asp:TextBox runat="server" ID="FirstNameTextBox" /></td>
</tr>
<tr>
<td><asp:Label ID="LastNameLabel" runat="server" AssociatedControlID="LastNameTextBox"
Text="Last Name" ForeColor="White" /></td>
<td><asp:TextBox runat="server" ID="LastNameTextBox" /></td>
</tr>
<tr>
<td></td>
<td>
<asp:LinkButton ID="InsertButton" runat="server" Text="Insert" OnClick="InsertButton_Click" ForeColor="White" />
<asp:LinkButton ID="Cancelbutton" runat="server" Text="Cancel" OnClick="CancelButton_Click" ForeColor="White" />
</td>
</tr>
</table>
<asp:Label runat="server" ID="InputTimeLabel"><%=DateTime.Now %> </asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
</td>
<td style="height: 206px" valign="top">
<asp:UpdatePanel ID="EmployeesUpdatePanel" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:GridView ID="EmployeesGridView" runat="server" BackColor="LightGoldenrodYellow" BorderColor="Tan"
BorderWidth="1px" CellPadding="2" ForeColor="Black" GridLines="None" AutoGenerateColumns="False">
<FooterStyle BackColor="Tan" />
<SelectedRowStyle BackColor="DarkSlateBlue" ForeColor="GhostWhite" />
<PagerStyle BackColor="PaleGoldenrod" ForeColor="DarkSlateBlue" HorizontalAlign="Center" />
<HeaderStyle BackColor="Tan" Font-Bold="True" />
<AlternatingRowStyle BackColor="PaleGoldenrod" />
<Columns>
<asp:BoundField DataField="EmployeeID" HeaderText="Employee ID" />
<asp:BoundField DataField="LastName" HeaderText="Last Name" />
<asp:BoundField DataField="FirstName" HeaderText="First Name" />
</Columns>
<PagerSettings PageButtonCount="5" />
</asp:GridView>
<asp:Label runat="server" ID="ListTimeLabel"><%=DateTime.Now %> </asp:Label>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="InsertButton" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
</td>
</tr>
</table>
</form>
</body>
</html>
输入新员工
私人名单雇员名单;
受保护的无效页面加载()
{
如果(!IsPostBack)
{
EmployeeList=新列表();
添加(新员工(1,“跳转”、“跳转”);
新增(新员工(2名,“Kirwan”、“Yvette”);
ViewState[“员工列表”]=员工列表;
}
其他的
EmployeeList=(列表)视图状态[“EmployeeList”];
EmployeesGridView.DataSource=EmployeeList;
EmployeesGridView.DataBind();
}
受保护的void InsertButton_单击(对象发送方,事件参数e)
{
if(String.IsNullOrEmpty(FirstNameTextBox.Text)||
String.IsNullOrEmpty(LastNameTextBox.Text)){return;}
int employeeID=EmployeeList[EmployeeList.Count-1].employeeID+1;
字符串lastName=Server.HtmlEncode(FirstNameTextBox.Text);
字符串firstName=Server.HtmlEncode(LastNameTextBox.Text);
FirstNameTextBox.Text=String.Empty;
LastNameTextBox.Text=String.Empty;
添加(新员工(employeeID,lastName,firstName));
ViewState[“员工列表”]=员工列表;
EmployeesGridView.DataBind();
EmployeesGridView.PageIndex=EmployeesGridView.PageCount;
}
受保护的作废取消按钮\u单击(对象发送者,事件参数e)
{
FirstNameTextBox.Text=String.Empty;
LastNameTextBox.Text=String.Empty;
}
[可序列化]
公营雇员
{
私人国际雇员ID;
私有字符串_lastName;
私有字符串_firstName;
公共国际雇员ID
{
获取{return\u employeeID;}
}
公共字符串姓氏
{
获取{return\u lastName;}
}
公共字符串名
{
获取{return\u firstName;}
}
公共雇员(int employeeID、字符串lastName、字符串firstName)
{
_employeeID=employeeID;
_lastName=lastName;
_名字=名字;
}
}
Damon说得对,因为您正在寻找ajax,它应该为您提供所需的功能。我发现了一个使用gridview的frmo MSDN示例,但它应该是可适应的:
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Collections.Generic" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Enter New Employees</title>
<script runat="server">
private List<Employee> EmployeeList;
protected void Page_Load()
{
if (!IsPostBack)
{
EmployeeList = new List<Employee>();
EmployeeList.Add(new Employee(1, "Jump", "Dan"));
EmployeeList.Add(new Employee(2, "Kirwan", "Yvette"));
ViewState["EmployeeList"] = EmployeeList;
}
else
EmployeeList = (List<Employee>)ViewState["EmployeeList"];
EmployeesGridView.DataSource = EmployeeList;
EmployeesGridView.DataBind();
}
protected void InsertButton_Click(object sender, EventArgs e)
{
if (String.IsNullOrEmpty(FirstNameTextBox.Text) ||
String.IsNullOrEmpty(LastNameTextBox.Text)) { return; }
int employeeID = EmployeeList[EmployeeList.Count-1].EmployeeID + 1;
string lastName = Server.HtmlEncode(FirstNameTextBox.Text);
string firstName = Server.HtmlEncode(LastNameTextBox.Text);
FirstNameTextBox.Text = String.Empty;
LastNameTextBox.Text = String.Empty;
EmployeeList.Add(new Employee(employeeID, lastName, firstName));
ViewState["EmployeeList"] = EmployeeList;
EmployeesGridView.DataBind();
EmployeesGridView.PageIndex = EmployeesGridView.PageCount;
}
protected void CancelButton_Click(object sender, EventArgs e)
{
FirstNameTextBox.Text = String.Empty;
LastNameTextBox.Text = String.Empty;
}
[Serializable]
public class Employee
{
private int _employeeID;
private string _lastName;
private string _firstName;
public int EmployeeID
{
get { return _employeeID; }
}
public string LastName
{
get { return _lastName; }
}
public string FirstName
{
get { return _firstName; }
}
public Employee(int employeeID, string lastName, string firstName)
{
_employeeID = employeeID;
_lastName = lastName;
_firstName = firstName;
}
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
</div>
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true" />
<table>
<tr>
<td style="height: 206px" valign="top">
<asp:UpdatePanel ID="InsertEmployeeUpdatePanel" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<table cellpadding="2" border="0" style="background- color:#7C6F57">
<tr>
<td><asp:Label ID="FirstNameLabel" runat="server" AssociatedControlID="FirstNameTextBox"
Text="First Name" ForeColor="White" /></td>
<td><asp:TextBox runat="server" ID="FirstNameTextBox" /></td>
</tr>
<tr>
<td><asp:Label ID="LastNameLabel" runat="server" AssociatedControlID="LastNameTextBox"
Text="Last Name" ForeColor="White" /></td>
<td><asp:TextBox runat="server" ID="LastNameTextBox" /></td>
</tr>
<tr>
<td></td>
<td>
<asp:LinkButton ID="InsertButton" runat="server" Text="Insert" OnClick="InsertButton_Click" ForeColor="White" />
<asp:LinkButton ID="Cancelbutton" runat="server" Text="Cancel" OnClick="CancelButton_Click" ForeColor="White" />
</td>
</tr>
</table>
<asp:Label runat="server" ID="InputTimeLabel"><%=DateTime.Now %> </asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
</td>
<td style="height: 206px" valign="top">
<asp:UpdatePanel ID="EmployeesUpdatePanel" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:GridView ID="EmployeesGridView" runat="server" BackColor="LightGoldenrodYellow" BorderColor="Tan"
BorderWidth="1px" CellPadding="2" ForeColor="Black" GridLines="None" AutoGenerateColumns="False">
<FooterStyle BackColor="Tan" />
<SelectedRowStyle BackColor="DarkSlateBlue" ForeColor="GhostWhite" />
<PagerStyle BackColor="PaleGoldenrod" ForeColor="DarkSlateBlue" HorizontalAlign="Center" />
<HeaderStyle BackColor="Tan" Font-Bold="True" />
<AlternatingRowStyle BackColor="PaleGoldenrod" />
<Columns>
<asp:BoundField DataField="EmployeeID" HeaderText="Employee ID" />
<asp:BoundField DataField="LastName" HeaderText="Last Name" />
<asp:BoundField DataField="FirstName" HeaderText="First Name" />
</Columns>
<PagerSettings PageButtonCount="5" />
</asp:GridView>
<asp:Label runat="server" ID="ListTimeLabel"><%=DateTime.Now %> </asp:Label>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="InsertButton" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
</td>
</tr>
</table>
</form>
</body>
</html>
输入新员工
私人名单雇员名单;
受保护的无效页面加载()
{
如果(!IsPostBack)
{
EmployeeList=新列表();
添加(新员工(1,“跳转”、“跳转”);
新增(新员工(2名,“Kirwan”、“Yvette”);
ViewState[“员工列表”]=员工列表;
}
其他的
EmployeeList=(列表)视图状态[“EmployeeList”];
EmployeesGridView.DataSource=EmployeeList;
EmployeesGridView.DataBind();
}
受保护的void InsertButton_单击(对象发送方,事件参数e)
{
if(String.IsNullOrEmpty(FirstNameTextBox.Text)||
String.IsNullOrEmpty(LastNameTextBox.Text)){return;}
int employeeID=EmployeeList[EmployeeList.Count-1].employeeID+1;
字符串lastName=Server.HtmlEncode(FirstNameTextBox.Text);
字符串firstName=Server.HtmlEncode(LastNameTextBox.Text);
FirstNameTextBox.Text=String.Empty;
LastNameTextBox.Text=String.Empty;
添加(新员工(employeeID,lastName,firstName));
ViewState[“员工列表”]=员工列表;
EmployeesGridView.DataBind();
EmployeesGridView.PageIndex=EmployeesGridView.PageCount;
}
受保护的作废取消按钮\u单击(对象发送者,事件参数e)
{
FirstNameTextBox.Text=String.Empty;
LastNameTextBox.Text=String.Empty;
}
[可序列化]
公营雇员
{
私人国际雇员ID;
私有字符串_lastName;
私有字符串_firstName;
公共int雇员
<select id='ddl' onchange='document.getElementById("<%= hidValue.ClientID %>").value=this.value'>
<option value=''>Loading...</option>
</select>
<asp:Hidden runat='server' id='hidValue' />
$(function(){
$.ajax("... your api endpoit").then(function(result){
var items = result.items; // actual implementation will change
var ddl = $(ddl);
ddl.html(''); // remove the 'loading' option.
foreach(var item in items) {
var option = $("<option>");
option.attr("value",item.value);
option.text(item.text);
ddl.append(option);
}
});
});