使用实体框架时失去响应能力

本文关键字:失去 响应 能力 框架 实体 | 更新日期: 2023-09-27 18:19:48

为了简化,我将去掉后面的业务规则:

我正在从WCF中获取数据并填充网格。在后台,我会检查记录是否已经存在,如果不存在,我会通过EF将其添加到表中。在EF采取行动之前,一切都很好,反应灵敏。代码如下:

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线程中执行,因为Control.BeginVoke方法不应该在后台线程中运行委托。若要异步执行代码,请使用委托的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;
    }
}