线程完成时关闭窗体
本文关键字:窗体 完成时 线程 | 更新日期: 2023-09-27 18:00:20
每个人。
我有两张下面的表格
-
From1有一个按钮,当点击这个Form2时就会出现。
-
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();
}
}