线程完成时关闭窗体

本文关键字:窗体 完成时 线程 | 更新日期: 2023-09-27 18:00:20

每个人。

我有两张下面的表格

  1. From1有一个按钮,当点击这个Form2时就会出现。

  2. From2有一个Progressbar,它从Maximun值开始计数并更新Progressbar直到它完成,Form2将关闭。

这是Form2 的以下代码

public delegate void ProgressbarHandler(int value);
public partial class Form2 : Form
{
    public event WaitCallback CloseThreadEvent;
    private Thread t;
    public void OnCloseEvent(ThreadState state)
    {
        if (CloseThreadEvent != null)
            CloseThreadEvent(state);
    }
    public Form2()
    {
        InitializeComponent();
        progressBar1.Minimum = 0;
        progressBar1.Maximum = 20000;
    }
    private void Form2_Load(object sender, EventArgs e)
    {
        InitThread();
    }
    private void InitThread()
    {
        t = new Thread(new ThreadStart(RunThread));
        t.Start();
        CloseThreadEvent += new WaitCallback(CloseForm);
        Thread tt = new Thread(ThreadObserver);
        tt.IsBackground = true;
        tt.Start();
    }
    private void RunThread()
    {
        for (int i = 0; i < progressBar1.Maximum; i++)
        {
            progressBar1.Invoke(new ProgressbarHandler(UpdateProgressbar), i);
        }
    }
    private void UpdateProgressbar(int value)
    {
        progressBar1.Value = value + 1;
    }
    private void ThreadObserver()
    {
        while (t.IsAlive)
        {
            OnCloseEvent(t.ThreadState);
        }
    }
    private void CloseForm(Object state)
    {
        if ((ThreadState)state == ThreadState.Stopped)
            this.Close();
    }
}

根据我的代码,它在上有一个"跨线程操作无效"错误

this.Close();

请给出建议,如何按照我的目的进行编码。

谢谢。

线程完成时关闭窗体

您只能从创建控件的线程访问控件。窗体也是控件。

看一下Control.Invoke

我使用类似的类来处理这些场景:

public static class ControlExtensions
{
    public static void Invoke(this Control control, Action action)
    {
        if (control.InvokeRequired)
        {
            control.Invoke(new MethodInvoker(action), null);
        }
        else
        {
            action.Invoke();
        }
    }
}

然后您就可以调用this.Invoke(() => Close());来关闭您的表单。

非常简单的修复。

this.Invoke(new MethodInvoker(delegate { this.Close(); }));

我不知道你为什么没有想到?这不是很明显吗?:P

谢谢大家

它有效!!

    public partial class Form2 : Form
{  
    private Thread tstart, trun;
    public Form2()
    {
        InitializeComponent();
        progressBar1.Minimum = 0;
        progressBar1.Maximum = 100;
    }
    private void Form2_Load(object sender, EventArgs e)
    {
        tstart = new Thread(InitThread);
        tstart.Start();
    }
    private void InitThread()
    {
        trun = new Thread(new ThreadStart(RunThread));
        trun.Start();
        trun.Join();
        CloseForm(trun.ThreadState);
    }
    private void RunThread()
    {
        for (int i = 0; i < progressBar1.Maximum; i++)
        {
            Thread.Sleep(10);
            progressBar1.Invoke(new MethodInvoker(delegate { progressBar1.Increment(1); }));                            
        }
    }
    private void CloseForm(Object state)
    {
        if ((ThreadState)state != ThreadState.Stopped)               
            return;            
        else
        {
            if (this.InvokeRequired)
                this.Invoke(new MethodInvoker(delegate { this.Close(); }), null);
        }
    }
    private void Form2_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (tstart.IsAlive)
            tstart.Abort();
        if (trun.IsAlive)
            trun.Abort();
    }
}