我需要跟踪我创建的所有线程何时完成。在过去的两天里,我经过搜索并尝试了一些例子后无效,并想知道我是否能得到一些帮助。 提前谢谢。
根据用户检查的复选框,我的表单会根据按钮点击运行一系列查询。这些复选框中的每一个都有自己的线程,可以在按钮单击时创建。根据复选框选择填充数据网格视图和图表。
这是按钮单击和正在创建的两个线程。 我在查询运行时禁用了表单上的控件,因为我不希望用户能够在另一个处理时发送另一个查询请求。
我是否有一种方法可以不断检查我的线程是否已完成,然后重新启用我的表单控件?
public void btn_runGRM_Click(object sender, EventArgs e)
{
this.btn_runGRM.Enabled = false;
this.checkBox_Assgn.Enabled = false;
this.checkBox_Avail.Enabled = false;
this.checkBox_RFI.Enabled = false;
this.checkBox_Census.Enabled = false;
this.ChartDGV.Visible = true;
if (checkBox_Assgn.Checked)
{
AssignmentDGV.DataSource = null;
AssignmentDGV.Rows.Clear();
AssignmentDGV.Refresh();
Assgn_timer = new System.Windows.Forms.Timer();
Assgn_timer.Interval = (1000);
Assgn_timer.Tick += new EventHandler(Assgn_timer_Tick);
Assgn_sw = new System.Diagnostics.Stopwatch();
Assgn_timer.Start();
Assgn_sw.Start();
ThreadStart childref1 = new ThreadStart(CallToChildthread1);
Thread childThread1 = new Thread(childref1);
childThread1.Start();
}
if (checkBox_Census.Checked)
{
CensusDGV.DataSource = null;
CensusDGV.Rows.Clear();
CensusDGV.Refresh();
Census_timer = new System.Windows.Forms.Timer();
Census_timer.Interval = (1000);
Census_timer.Tick += new EventHandler(Census_timer_Tick);
Census_sw = new System.Diagnostics.Stopwatch();
Census_timer.Start();
Census_sw.Start();
ThreadStart childref2 = new ThreadStart(CallToChildthread2);
Thread childThread2 = new Thread(childref2);
childThread2.Start();
}
}
以下是来自其中一个子线程
的一些代码public void CallToChildthread1()
{
string oradb = "......";
OracleConnection conn = new OracleConnection(oradb); // C#
conn.Open();
OracleParameter parm = new OracleParameter();
parm.OracleDbType = OracleDbType.Varchar2;
if (textBox1.Text == "")
{
parm.Value = ' ';
}
else
{
parm.Value = textBox1.Text;
}
cmd = new OracleCommand();
cmd.Connection = conn;
cmd.Parameters.Add(parm);
cmd.CommandText = "SELECT .......";
}
答案 0 :(得分:0)
如果要在线程完成之前阻止执行,请使用
Thread childThread1 = new Thread(childref1);
...
childThread1.Join();
childThread2.Join();
// here i am sure two threads have finished
它将阻止执行直到完成。
请参阅here了解更多示例。
答案 1 :(得分:0)
使用任务。它们更容易使用。
<html>
<script src="jquery-3.1.1.min.js"></script>
<body>
<a href="https://www.science.gov" id="navigate">science</a>
</body>
<script>
$(window).on('beforeunload', function(){ return prompt('Are you sure you want to leave?');});
</script> </html>
答案 2 :(得分:0)
所以在今天进行了大约8个小时的研究之后,我找到了一个适合我的解决方案。
在我最终让事情为我工作之前,我可能会看到大约10种不同的做事方式。
我可以在5小时前得到一个解决方案,但我没有意识到,当做一个while循环时,你必须调用Forms.Application.DoEvents();
才能使UI可用。
在我想出来之后,我在尝试评估所有线程的状态时仍然会收到错误,我将在下面详述。
创建处理我的线程的方法
public Thread thrd1;
public Thread thrd3;
public void MakeThread1(ThreadStart name)
{
thrd1 = new Thread(name);
thrd1.Start();
}
public void MakeThread3(ThreadStart name)
{
thrd3 = new Thread(name);
thrd3.Start();
}
以下仅与我最初发布的内容略有不同。我调用方法而不是从按钮单击中启动线程。
public void btn_runGRM_Click(object sender, EventArgs e)
{
this.btn_runGRM.Enabled = false;
this.checkBox_Assgn.Enabled = false;
this.checkBox_Avail.Enabled = false;
this.checkBox_RFI.Enabled = false;
this.checkBox_Census.Enabled = false;
this.ChartDGV.Visible = true;
if (checkBox_Assgn.Checked)
{
AssignmentDGV.DataSource = null;
AssignmentDGV.Rows.Clear();
AssignmentDGV.Refresh();
ThreadStart childref1 = new ThreadStart(CallToChildthread1);
Thread mt1 = new Thread(childref1);
MakeThread1(childref1);
}
if (checkBox_Assgn.Checked || checkBox_RFI.Checked)
{
while (chart1.Series.Count > 0) { chart1.Series.RemoveAt(0); }
chart1.Visible = true;
ChartDGV.DataSource = null;
ChartDGV.Rows.Clear();
ChartDGV.Refresh();
ThreadStart childref3 = new ThreadStart(CallToChildthread3);
Thread mt3 = new Thread(childref3);
MakeThread3(childref3);
}
当仍然在按钮内部时,我现在看看线程是否为空。如果是这样会抛出错误。如果不是,我开始我的while循环。
if(thrd1 != null)
{
while (thrd1.IsAlive == true)
try
{
Thread.Sleep(50);
System.Windows.Forms.Application.DoEvents();
}
catch
{
}
}
if (thrd3 != null)
{
while (thrd3.IsAlive == true)
try
{
Thread.Sleep(50);
System.Windows.Forms.Application.DoEvents();
}
catch
{
}
}
this.btn_runGRM.Enabled = true;
this.checkBox_Assgn.Enabled = true;
this.checkBox_Avail.Enabled = true;
this.checkBox_RFI.Enabled = true;
this.checkBox_Census.Enabled = true;
}
我将尝试组合thrd为null并且thrd是活着的评估,看看我是否不能简化代码的外观。 也许就像......
while((thrd1.IsAlive!=Null && thrd1.Isalive== true) ||
(thrd3.IsAlive!=Null && thrd3.Isalive== true))