读书人

一个多线程的有关问题 小弟我个人感

发布时间: 2013-10-17 17:26:17 作者: rapoo

一个多线程的问题 ,我个人感觉绝对属于C#的bug,当然也可能是我本身能力太逊,请大家看看,出出主意
之前有个报表的程序,其中有一张报表速度比较慢。所以就加了个多线程。代码大致如下,有个query函数,然后我加了个thread指向他 tempt = new Thread(new ThreadStart(Query)); query函数里面是个while循环,
如下,其中根据 combo_ReportType的值 去做case when

代码如下
while (true)
{
btn_query.Enabled = false;
this.dgv_Report.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
String ReportSql = string.Empty;
switch (combo_ReportType.Text)
{
case "":
MessageBox.Show("请选择一个确定的报表!");
break;
case "急诊就诊量统计":
ReportSql = "ReportEmergencyMentimes " + dt_Start.Value.Year.ToString();
break;
case "急诊就诊量统计按日统计":
ReportSql = "ReportEmergencyMentimesByDays " + dt_Start.Value.Year.ToString() + "," + dt_Start.Value.Month.ToString();
break;
case "急诊留观病人信息表":
ReportSql = "OutComeReport " + SqlProcess.SqlProcess.Blank(dt_Start.Value.ToShortDateString()) + "," + SqlProcess.SqlProcess.Blank(dt_End.Value.AddDays(1).ToShortDateString());
break;
case "急诊死亡病人信息表":
this.dgv_Report.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
ReportSql = "DeathReport " + SqlProcess.SqlProcess.Blank(dt_Start.Value.ToShortDateString()) + "," + SqlProcess.SqlProcess.Blank(dt_End.Value.AddDays(1).ToShortDateString());
break;
case "急诊留观汇总报表":
ReportSql = "OutComeReportHZ " + SqlProcess.SqlProcess.Blank(dt_Start.Value.ToShortDateString()) + "," + SqlProcess.SqlProcess.Blank(dt_End.Value.AddDays(1).ToShortDateString());
break;
default:
break;

}
if (String.IsNullOrEmpty(ReportSql) == false)
{
RefreshGrid(ReportSql, "");
}

if (dgv_Report.Columns.Contains("deptid"))


{
dgv_Report.Columns["deptid"].Visible = false;
}
if (dgv_Report.Columns.Contains("regid"))
{
dgv_Report.Columns["regid"].Visible = false;
}
if (dgv_Report.Columns.Contains("cardid"))
{
dgv_Report.Columns["cardid"].Visible = false;
}
if (dgv_Report.Columns.Contains("pid"))
{
dgv_Report.Columns["pid"].Visible = false;
}
btn_query.Enabled = true;
tempt.Suspend();

}
while循环的最后我会suspend();然后 有个专门的按钮,我点击之后 会让线程resume,这样的话又会重新执行while循环 。button里面的代码是
if (tempt.ThreadState == ThreadState.Suspended)
tempt.Resume();
else
tempt.Start();


个人感觉应该逻辑上没有什么问题,但是现在就是当combobox的值是“急诊留观病人信息表”的时候,窗体就会直接卡死。
但是请注意,我这段逻辑代码不用多线程的时候完全没有问题。而且case的差别不过是datagridview绑定的那个sql语句的不同。每句sql语句都能执行无误。
所以就觉得非常的奇怪,现在只好把这个case的情况拉到多线程外面去执行,也没有问题。大家说,这个问题大概是什么原因造成的

多线程 bug datagridview thread
[解决办法]
代码有问题和对线程基本知识了解不够,不是C#Bug。
1、多线程安全访问控件;
2、一个线程只会启动一次,中途可暂停(通常人为阻塞或等待信号),但运行完后也就结束了;
3、你要实现多线程暂停或继续应该使用线程同步或信号,这方面有很多资料的。
4、?
[解决办法]
CheckForIllegalCrossThreadCalls = false
并不会对你的多线程有任何改善,而且也不推荐这么做。它一样会造成主界面阻塞。
[解决办法]
http://201211131343.iteye.com/blog/1828965

http://smycll.blog.163.com/blog/static/123739963201322782618719/

http://msdn.microsoft.com/zh-cn/library/system.threading.thread.suspend.ASPX
不要使用 Suspend 和 Resume 方法来同步线程的活动。 您无法知道挂起线程时它正在执行什么代码。 如果您在安全权限评估期间挂起持有锁的线程,则 AppDomain 中的其他线程可能被阻止。 如果您在线程正在执行类构造函数时挂起它,则 AppDomain 中尝试使用该类的其他线程将被阻止。 这样很容易发生死锁。

读书人网 >C#

热点推荐