之前有个报表的程序,其中有一张报表速度比较慢。所以就加了个多线程。代码大致如下,有个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的情况拉到多线程外面去执行,也没有问题。大家说,这个问题大概是什么原因造成的 多线程bugdatagridviewthread
如下,其中根据 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的情况拉到多线程外面去执行,也没有问题。大家说,这个问题大概是什么原因造成的 多线程bugdatagridviewthread
解决方案 »
- “WCF服务”的数据库连接问题?
- winform中DataGridView绑定数据。
- C#问题:在实现线程间通信时除了使用线程公用变量之外还有没有其他更直观的通信方法?
- 如何用程序实现 - 将网页上的PDF文件下载到本地? 高手进
- 在编译#develop项目的范例程序 LineCounter的时候遇到类型转换错误
- 在WinForm中点按钮时,出现正在查询,是怎么实现的
- 使用VS2005的时候遇到一个问题
- 求如何设置datagrid!
- 那位能提供一下c#.net的常用参数?急用!
- 我应该选择哪一种开发语言作为我的主开发语言(网络通讯)
- C#网吧管理软件是如何做到屏蔽界面某些快捷键,只能点击登陆的
- 如何触发PrintDocument的PrintPage事件但是不打印
1、多线程安全访问控件;
2、一个线程只会启动一次,中途可暂停(通常人为阻塞或等待信号),但运行完后也就结束了;
3、你要实现多线程暂停或继续应该使用线程同步或信号,这方面有很多资料的。
4、?
2。我那个线程也只启动一次 。由于是while循环,所以从来没结束过。我只是中途认为的suspend和resume
并不会对你的多线程有任何改善,而且也不推荐这么做。它一样会造成主界面阻塞。
不要使用 Suspend 和 Resume 方法来同步线程的活动。 您无法知道挂起线程时它正在执行什么代码。 如果您在安全权限评估期间挂起持有锁的线程,则 AppDomain 中的其他线程可能被阻止。 如果您在线程正在执行类构造函数时挂起它,则 AppDomain 中尝试使用该类的其他线程将被阻止。 这样很容易发生死锁。