[英]How to constantly check if threads are alive
我需要跟蹤我創建的所有線程何時完成。 在過去的兩天里,我一直在逐例搜索和嘗試,但無濟於事,我想知道是否可以得到一些幫助。 先感謝您。
我的表單基於用戶選中的復選框在按鈕單擊上運行一系列查詢。 這些復選框中的每一個都有其自己的線程,這些線程在單擊按鈕時創建。 根據復選框選擇填充Datagridviews和圖形。
這是單擊按鈕和正在創建的兩個線程。 我在查詢運行時禁用了表單上的控件,因為我不希望用戶在另一個正在處理的同時發送另一個查詢請求。
有沒有一種方法可以使我不斷檢查線程是否已完成,然后重新啟用表單控件?
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 .......";
}
如果要在線程完成之前阻止執行,請使用
Thread childThread1 = new Thread(childref1);
...
childThread1.Join();
childThread2.Join();
// here i am sure two threads have finished
它將阻止執行直到完成。
有關更多示例,請參見此處 。
使用任務。 它們更易於使用。
private void StartTasksAndWaitForThemToFinish() {
// Generate and start worker tasks
Task[] tasks = new [] {
TaskFactory.StartNew(() => {
// task 1
}),
TaskFactory.StartNew(() => {
// task 2
})
};
// Wait for them to finish
Task.WaitAll(tasks);
// Update UI. You might need to invoke to the UI thread.
...
}
private void SomeButtonClickHandler(object sender, EventArgs e) {
// Start tasks and wait for them to finish
TaskFactory.StartNew(StartTasksAndWaitForThemToFinish);
}
因此,經過大約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))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.