开发者

how can i stop a thread on a usercontrol when the form is closed

I have a user control with the following code in it:

private Thread updateProgress;
private void FileUploadingScreen_Load(object sender, EventArgs e)
{
    updateProgress = new Thread(UpdateProgressBar);
    updateProgress.Start();
}
private bool run = true;
private void UpdateProgressBar()
{
    while (run)
    {
        Thread.Sleep(100);
        if(run)
        {
           progressBar1.Invoke(new Action(() =>
           {
               if (progressBar1.Value >= 100)
               {
                    progressBar1.Value = 1;
                    progressBar1.Step = 1;
               }
               progressBar1.PerformStep();
           }));
        }
    }
}

public void StopProgressBar()
{
    run = false;
}

on the parent form I have :

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    userControl.StopProgressBar();
}

when I close the form by clicking the X I'm getting the following error on the progressBar1.Invoke line.

Invoke or BeginInvoke 开发者_JAVA百科cannot be called on a control until the window handle has been created.

I thought setting run to false in the form_closing event would stop this from happening. How can I fix this? My main goal is to have a progressbar that keeps moving to show that something is happening still. Is there a better way to do this?


You can use this

public void StopProgressBar()
{
    updateProgress.Abort();
}

I think it's a valid approach. The application will keep running because there's a thread still active. Aborting that thread shuts it all down.

However, calling this manually every time from outside the UserControl is tedious. You're better off making your user control self-managing and clean up after itself.

As per this discussion, changing the control's Dispose method in Designer.cs is safe, VS should respect these changes and not overwrite them.

protected override void Dispose(bool disposing)
{
    if (disposing && (components != null))
    {
        components.Dispose();
    }
    //Special handling of started thread
    if (disposing && updateProgress.IsAlive)
    {
        updateProgress.Abort();
    }
    base.Dispose(disposing);
}

With this, your parent form does not have to call StopProgressBar explicitly.


Try

public void StopProgressBar()
{
    run = false;
    updateProgress.Join();
}

The problem is that you're assuming that as soon as you set 'run' to false, the thread is going to stop. What's happening is that Windows continues disposing the window while your thread is still being executed. What this solution does is block until the thread completes execution.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜