如何不断检查线程是否存活

时间:2017-03-16 13:26:00

标签: c# multithreading winforms

我需要跟踪我创建的所有线程何时完成。在过去的两天里,我经过搜索并尝试了一些例子后无效,并想知道我是否能得到一些帮助。 提前谢谢。

根据用户检查的复选框,我的表单会根据按钮点击运行一系列查询。这些复选框中的每一个都有自己的线程,可以在按钮单击时创建。根据复选框选择填充数据网格视图和图表。

这是按钮单击和正在创建的两个线程。 我在查询运行时禁用了表单上的控件,因为我不希望用户能够在另一个处理时发送另一个查询请求。

我是否有一种方法可以不断检查我的线程是否已完成,然后重新启用我的表单控件?

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 .......";
}

3 个答案:

答案 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))