在关闭表单之前停止一个线程

时间:2016-06-22 18:02:55

标签: c# multithreading asynchronous invoke begininvoke

使用.NET4,c#, 我在winform上有一个网格。当我点击进程按钮时,我需要在每一行上执行一些步骤,然后使用结果更新行。这样,用户可以在下一行处理时看到进度。如果用户点击取消或关闭表单,我需要完成当前行的过程,然后打破或关闭表单。根据我的研究,这是我想出的。我有2个问题。

这是我的代码:

delegate void OperateGridMethodDelegate();
delegate void UpdateProgressDelegate(int rowIndex, string msg);
bool isCancelled = false;


private void ButtonOne_Click(object sender, EventArgs e)
{
    isCancelled=false;
    OperateGridMethodDelegate delegate = new OperateGridMethodDelegate(LongProcess);`
    delegate.BeginInvoke(null,null);

}

private void ButtonTow_Click(object sender, EventArgs e)
{

    MyButtonOne.Enabled=false;
    isCancelled=true;

}

private void LongProcess()
{

    foreach (DataRow row in dataTableOne.Rows)
    {
        //Do Lengthy Process

        DisplayResult( rowIndex, "this is result of operation" );
        if(isCancelled)
        {
            MyButtonOne.Enabled=true;
            break;

        }

    }

}

private void DisplayResult(int rowIndex,string message)
{

    if(myGrid.InvokeRequired == false)
    {

        myGrid.Rows[rowIndex].value = message;

    }

    else
    {

        UpdateProgressDelegate delegate = new  UpdateProgressDelegate(DisplayResult);
        myGrid.BeginInvoke(delegate, new object[] { rowIndex, message });

    }

}

我留下的两个问题是:

  1. 当表单关闭时,我想等待LongProcess(由我的OperateGridMethodDelegate调用)完成它的行然后取消(与ButtonTwo相同),但我无法让它发挥作用。

  2. 我在调试时注意到一种奇怪的行为,我不确定这是一个错误还是正确,当一行完成处理时,结果不会被设置。而是处理下一行,然后显示前一行结果。当第三行结束时显示第二行结果等。然后最后两行结果基本上同时显示。

  3. 我接近这个吗?

1 个答案:

答案 0 :(得分:0)

如果你在一个帖子中启动了一些任务,等到它完成后再继续你可以这样做:

yourThread.Join();

这将阻塞直到线程退出。您可能希望在Form_Closing事件

中使用类似的内容

或者,如果您希望线程在应用程序终止时自动终止,则需要设置线程的background属性:

yourThread.IsBackground = true;

这意味着它是主(UI)线程的后台线程,因此它将以主线程结束。

编辑:

使用您自己的主题:

private Thread yourThread = new Thread(() = > LongProcess());
yourThread.IsBackground = true;
yourThread.Start();  // This will begin your 'LongProcess' function.

现在,如果你想阻止某个地方并等待它完成,你可以做我先提到的:yourThread.Join();

另请注意,如果您设置IsBackground = false并且某人关闭了该应用程序,该线程将不会立即退出,它将一直持续到完成,尽管UI窗口已关闭。