使用backgroundWorker组件,为什么还会占用主线程,导致卡的现象?

quanpp 2012-07-25 12:15:09
直接贴代码
打断点看的时候,主线程执行完backgroundWorker1.RunWorkerAsync();后 断点出了这里-> } 就一直卡着界面,要等OldUpload运行完才有反应

private void btnOldUpload_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
OldUpload();
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
Console.WriteLine("error");
else
{
MSG("上传结束!");
}
}

/**需要长时间执行的方法**/
private void OldUpload()
{
int ucount = dgvUsers.Rows.Count;
int mcount = dgvOldMachines.Rows.Count;
for (int i = 0; i < mcount; i++)//
{
dgvOldMachines.EndEdit();

DataGridViewCheckBoxCell ckoldmachine = (DataGridViewCheckBoxCell)dgvOldMachines.Rows[i].Cells["xuanold"];
Boolean flag = Convert.ToBoolean(ckoldmachine.Value);
if (flag == true)//datagridview 设备选中的信息 {
int iMachineNumber = Convert.ToInt32(dgvOldMachines.Rows[i].Cells[2].Value.ToString());
MachineInfo m = MachineInfoBLL.SelectMachineInfoByEqpID(iMachineNumber.ToString());

for (int j = 0; j < ucount; j++)
{
dgvUsers.EndEdit();
DataGridViewCheckBoxCell checkcell = (DataGridViewCheckBoxCell)dgvUsers.Rows[j].Cells["Column1"];
Boolean flagm = Convert.ToBoolean(checkcell.Value);

if (flagm == true)//datagridview人员选中的信息
{
try
{
int idwEnrollNumber = Convert.ToInt32(dgvUsers.Rows[j].Cells[1].Value.ToString());
string sName = dgvUsers.Rows[j].Cells[2].Value.ToString();
if (Connect(axCZKEM1, m.Ip, m.Port, iMachineNumber.ToString(), Convert.ToInt32(m.Commpassword)))
{
// MSG("连接成功!");
int idwErrorCode = 0;

int idwFingerIndex = 0;
string sTmpData = "";
int iPrivilege = 0;
bool bEnabled = true;
int iUpdateFlag = 1;
string sPassword = "";
int iFlag = 1;

axCZKEM1.EnableDevice(iMachineNumber, false);
int iLastEnrollNumber = 0;//判断是否已上传用户信息

if (axCZKEM1.BeginBatchUpdate(iMachineNumber, iUpdateFlag))//创建批处理数据的内存空间
{
List<TempLate> tl = TempLateBLL.GetOldTempLateBySSN(idwEnrollNumber.ToString());//根据考勤号查询新机器指纹信息
if (tl.Count != 0)
{
foreach (TempLate t in tl)
{
idwFingerIndex = t.Fingerid;
sTmpData = t.Template;
if (idwEnrollNumber != iLastEnrollNumber)//判断是否已上传用户信息(指纹信息除外)
{
if (axCZKEM1.SetUserInfo(iMachineNumber, idwEnrollNumber, sName, sPassword, iPrivilege, bEnabled))//上传用户信息到内存
{
axCZKEM1.SetUserTmpStr(iMachineNumber, idwEnrollNumber, idwFingerIndex, sTmpData);//上传指纹信息到内存
// MSG("上传用户" + idwEnrollNumber.ToString() + "信息成功,指纹ID" + idwFingerIndex + ",指纹长度" + sTmpData.Length + "");
}
else
{
axCZKEM1.GetLastError(ref idwErrorCode);
axCZKEM1.EnableDevice(iMachineNumber, true);

MessageBox.Show("Operation failed,ErrorCode=" + idwErrorCode.ToString(), "Error");
return;
}
}
else//一个用户拥有多个指纹模板的情况
{
axCZKEM1.SetUserTmpStr(iMachineNumber, idwEnrollNumber, idwFingerIndex, sTmpData);//上传指纹模板
// MSG("上传用户" + idwEnrollNumber.ToString() + "信息成功,指纹ID" + idwFingerIndex + ",指纹长度" + sTmpData.Length + "");
}
iLastEnrollNumber = idwEnrollNumber;//动态地改变值

}
axCZKEM1.BatchUpdate(iMachineNumber);//上传所有信息到内存
axCZKEM1.RefreshData(iMachineNumber);//机器数据刷新

axCZKEM1.EnableDevice(iMachineNumber, true);//启用设备

}
else
{
// MSG("数据库里没有数据,请先在线上传指纹!");
}
}
}
}
catch (Exception ex)
{

MessageBox.Show(ex.ToString());
}
finally
{
axCZKEM1.EnableDevice(iMachineNumber, true);
axCZKEM1.Disconnect();
}
}
}
}
}

private void MSG(string body)
{
this.BeginInvoke((MethodInvoker)(() =>
{
dgvMessages.Rows.Add(new string[] { (dgvMessages.Rows.Count + 1).ToString(), body, DateTime.Now.ToString() });
dgvMessages.FirstDisplayedScrollingRowIndex = dgvMessages.Rows.Count - 1;
}));
}
...全文
501 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
lotusroll 2014-09-19
  • 打赏
  • 举报
回复
请问是指组件类吗?我也碰到了这个问题
quanpp 2012-07-26
  • 打赏
  • 举报
回复
找到原因了,初始化开发包类的时候不能设为public 全局变量,要放在方法里new。
quanpp 2012-07-25
  • 打赏
  • 举报
回复
是什么原因导致主线程卡呢? 很费解啊。。
quanpp 2012-07-25
  • 打赏
  • 举报
回复
OldUpload 方法里 只调用connect方法 主界面也会卡
private void OldUpload()
{
Connect("a","b"..);
}

所以好像不是DGV的问题
effun 2012-07-25
  • 打赏
  • 举报
回复
楼主建议你不要在OldUpload里去解析DataGridView单元格的值,而应该直接去读数据源对象的属性。
effun 2012-07-25
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

引用 2 楼 的回复:

很奇怪,在OldUpload的线程里可以访问界面上的控件吗?

有些属性是可以访问的,如果访问的属性涉及到句柄问题,就会报错
[/Quote]

原来是这样,那有可能DGV为了线程安全性,在访问某些成员的时候进行了线程同步,所以会造成界面卡死。
bdmh 2012-07-25
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

很奇怪,在OldUpload的线程里可以访问界面上的控件吗?
[/Quote]
有些属性是可以访问的,如果访问的属性涉及到句柄问题,就会报错
effun 2012-07-25
  • 打赏
  • 举报
回复
很奇怪,在OldUpload的线程里可以访问界面上的控件吗?

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧