我可以在另一个线程上放置一个取消按钮吗?

时间:2019-06-29 14:54:59

标签: c# multithreading forms winforms

我正在做一个小项目,从另一个过程中打开一个Windows窗体以显示进度条。

所以我的表单代码如下:

public partial class ProgressForm : Form
{
    int currentValue = 0;
    int pbMax;
    bool cancelled = false;
    public ProgressForm(int pbMax)
    {
        InitializeComponent();
        this.pbMax = pbMax;
        this.progressBar1.Maximum = pbMax;
    }

    public void updateProgressBar(int newValue)
    {
        currentValue = newValue;
        this.progressBar1.Value = newValue;
    }
    public bool getCancelledStatus()
    {
        return cancelled;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        this.cancelled = true;
    }
}

其中button1是我的“取消”按钮。

我的计划是使用户能够通过单击“取消”按钮来取消其他任务的进度。

我其他任务中的代码是:

ProgressForm pf = new ProgressForm(MaxValue);
pf.Show();
bool cancelled = false;

 for (int i = 0; i<pbMax; i++)
 {
     if (cancelled == true)
         break;
       pf.updateProgressBar(i + 1);


/***** DO WORK HERE ******/

cancelled = pf.getCancelledStatus();

}

但是我什至不能单击取消按钮。显示进度条时,整个表单冻结。有什么我可以做的吗?我可以使用线程之类的东西吗?

1 个答案:

答案 0 :(得分:-4)

您问题的最短答案: 在FOR {}循环中调用DoEvents()方法。 在循环中,Windows不会执行任何其他内部花边。通过DoEvents()调用,您的应用程序将能够参加Button1_Click事件,这将打破循环。

您的其他任务代码将变成这样:

ProgressForm pf = new ProgressForm(MaxValue);
pf.Show();
bool cancelled = false;
for (int i = 0; i<pbMax; i++)
{
    if (cancelled == true)
        break;
    pf.updateProgressBar(i + 1);
    Application.DoEvents();
    cancelled = pf.getCancelledStatus();
}

我相信您还应该在用户单击“进度”表单上的“取消”按钮时添加Form Close()调用,如下所示:

private void button1_Click(object sender, EventArgs e)
{
    this.cancelled = true;
    this.Close();
}

这样做,当用户单击ProgressForm上的“取消”按钮1时,您的For {}循环将中断,并且ProgressForm将关闭。

这可以解决问题!

但是,长话大说,我建议您使用Timer控件实现与上面相同的逻辑,这可能会更优雅并且不会挂起您的应用程序。但这只是一个建议。

祝你好运!