C# 使用实体框架时失去响应能力
为了简化,我将去掉业务规则: 我正在从WCF获取数据并填写表格。在后台,我检查记录是否已经存在,若不存在,我将通过EF将其添加到表中。在EF采取行动之前,一切都很好,反应迅速。代码如下所示:C# 使用实体框架时失去响应能力,c#,winforms,entity-framework,backgroundworker,C#,Winforms,Entity Framework,Backgroundworker,为了简化,我将去掉业务规则: 我正在从WCF获取数据并填写表格。在后台,我检查记录是否已经存在,若不存在,我将通过EF将其添加到表中。在EF采取行动之前,一切都很好,反应迅速。代码如下所示: var ds = client.GetInfo(id,cb_TrackMembers_StartDate.Checked ? dtp_StartDate.Value : (Dat
var ds = client.GetInfo(id,cb_TrackMembers_StartDate.Checked ? dtp_StartDate.Value
: (DateTime?)null,
cb_EndDate.Checked
? dtp_EndDate.Value
: (DateTime?)null,
cb_CompletedOnly.Checked);
DataTable tables = ds.Tables["Table1"];
async_fillgridwithdatatable(gv_source, tables);
private void async_fillgridwithdatatable(DataGridView grid, DataTable table)
{
MethodInvoker action = delegate
{
grid.Rows.Clear();
var existing = db.GetMemberList();
foreach (DataRow row in table.Rows)
{
var username = row["Q51_1"].ToString();
if (!existing.Contains(username))
{
MyDirHelper ldap = new MyDirHelper(username, "");
int acclvl = ldap.GetAccessLevel();
tbl_Member newMember = new tbl_Member
{
username = username,
first_name = row["Q9_1"].ToString(),
last_name = row["Q9_2"].ToString(),
.
.
.
id_accesslevel = db.DB_GetMemberAutoAccessLevelIDByLDAPAccessLevel(acclvl),
created_on = DateTime.Now,
created_by = db.GetUser(E_Username).id_user,
modified_by = db.GetUser(E_Username).id_user,
modified_on = DateTime.Now
};
db.InsertIntoMembersEntity(newMember);
if (newMember.id_accesslevel != 1)
{
if (newMember.id_accesslevel != null)
{
mail_sendWelcome(newMember.email, newMember.id_accesslevel.Value);
db.UpdateMemberWelcomeMailSentDate(newMember.id_member, DateTime.Now);
}
}
}
else
{
tbl_Member existingMember = db.GetMemberByLogin(username);
existingMember.first_name = row["Q9_1"].ToString();
existingMember.last_name = row["Q9_2"].ToString();
.
.
.
existingMember.modified_by = db.GetUser(E_Username).id_user;
existingMember.modified_on = DateTime.Now;
db.Save();
}
grid.Rows.Add(username);
}
};
grid.BeginInvoke(action);
}
有什么方法可以提高响应能力吗?在您的情况下,所有代码都在UI线程中执行,因为该方法不应该在后台线程中运行委托。要异步执行代码,请使用委托的BeginInvoke方法。例如:
private void async_fillgridwithdatatable(DataGridView grid, DataTable table)
{
Func<DataTable, IEnumerable<string>> action = new Func<DataTable, IEnumerable<string>>(UpdateDbAndGetData);
action.BeginInvoke(o => grid.Invoke(new Action<IEnumerable<string>>(rows => {
grid.Rows.Clear();
foreach (string username in rows)
grid.Rows.Add(username);
}),
action.EndInvoke(o)));
}
IEnumerable<String> UpdateDbAndGetData(DataTable table) {
var existing = db.GetMemberList();
foreach (DataRow row in table.Rows)
{
var username = row["Q51_1"].ToString();
if (!existing.Contains(username))
{
MyDirHelper ldap = new MyDirHelper(username, "");
int acclvl = ldap.GetAccessLevel();
tbl_Member newMember = new tbl_Member
{
username = username,
first_name = row["Q9_1"].ToString(),
last_name = row["Q9_2"].ToString(),
.
.
.
id_accesslevel = db.DB_GetMemberAutoAccessLevelIDByLDAPAccessLevel(acclvl),
created_on = DateTime.Now,
created_by = db.GetUser(E_Username).id_user,
modified_by = db.GetUser(E_Username).id_user,
modified_on = DateTime.Now
};
db.InsertIntoMembersEntity(newMember);
if (newMember.id_accesslevel != 1)
{
if (newMember.id_accesslevel != null)
{
mail_sendWelcome(newMember.email, newMember.id_accesslevel.Value);
db.UpdateMemberWelcomeMailSentDate(newMember.id_member, DateTime.Now);
}
}
}
else
{
tbl_Member existingMember = db.GetMemberByLogin(username);
existingMember.first_name = row["Q9_1"].ToString();
existingMember.last_name = row["Q9_2"].ToString();
.
.
.
existingMember.modified_by = db.GetUser(E_Username).id_user;
existingMember.modified_on = DateTime.Now;
db.Save();
}
yield return username;
}
}
private void async\u fillgridwithdatatable(DataGridView网格,DataTable表格)
{
Func action=新Func(UpdateDbAndGetData);
action.BeginInvoke(o=>grid.Invoke)(新操作(行=>{
grid.Rows.Clear();
foreach(行中的字符串用户名)
grid.Rows.Add(用户名);
}),
行动(o);;
}
IEnumerable UpdateDbAndGetData(数据表){
var existing=db.GetMemberList();
foreach(table.Rows中的DataRow行)
{
var username=row[“Q51_1”].ToString();
如果(!existing.Contains(用户名))
{
MyDirHelper ldap=新的MyDirHelper(用户名“”);
int acclvl=ldap.GetAccessLevel();
tbl_成员newMember=新tbl_成员
{
用户名=用户名,
first_name=行[“Q9_1”]。ToString(),
last_name=行[“Q9_2”]。ToString(),
.
.
.
id_accesslevel=db.db_GetMemberAutoAccessLevelIDByLDAPAccessLevel(acclvl),
创建时间=日期时间。现在,
创建人=db.GetUser(E\u用户名).id\u用户,
修改的用户=db.GetUser(E\u用户名).id\u用户,
modified_on=DateTime.Now
};
db.插入成员资格(新成员);
if(newMember.id\u accesslevel!=1)
{
if(newMember.id\u accesslevel!=null)
{
mail\u sendWelcome(newMember.email,newMember.id\u accesslevel.Value);
db.UpdateMemberWelcomeMailSentDate(newMember.id_member,DateTime.Now);
}
}
}
其他的
{
tbl_成员existingMember=db.GetMemberByLogin(用户名);
existingMember.first_name=行[“Q9_1”].ToString();
existingMember.last_name=行[“Q9_2”].ToString();
.
.
.
existingMember.modified_by=db.GetUser(E_用户名).id_user;
existingMember.modified_on=DateTime.Now;
db.Save();
}
返回用户名;
}
}
响应“松散”意味着将其释放。。。取消对它的限制。从形象上看,现在的性能是最好的。所以“松散”而不是“失去”的意思与你的意图相反。@JoelCoehoorn对,谢谢!我可以提醒自己“放松一下”,但我仍然无法解决这个问题。将我的代码更改为您的概念时,我出现了两个错误:1)newfunc(UpdateDbAndGetData)代码>->“UpdateDbAndGetData”的重载与委托“System.Func”匹配,因此可能需要更改此重载,以便UpdateDbAndGetData
将接受DataTable作为参数,如IEnumerableString方法签名2)action.BeginInvoke(…
->“BeginInvoke”方法没有重载。添加到数据库后,参数仍然无法使其工作以更新网格。嗨,Adrian!事实上,我的代码中有一个错误。委托应该有一个DataTable类型的参数。我已在回答中更正了此错误。至于BeginInvoke的第二个参数,我ethod,我在代码段中使用了action.EndInvoke()结果。可能您错过了这一部分。