大家。
我有以下两种形式
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();
请提出建议,如何根据我的目的编码。
谢谢。
答案 0 :(得分:3)
您只能从创建它们的线程访问控件。表格也是一种控制。
查看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());
关闭表单。
答案 1 :(得分:2)
非常简单的修复。
this.Invoke(new MethodInvoker(delegate { this.Close(); }));
我不知道你为什么没想到它?不是很明显吗? :P
答案 2 :(得分:0)
谢谢大家
它有效!!
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();
}
}