我在一个按钮的单击事件里启动了一个线程,做一个耗时的操作,同时在这个操作了动态改变主窗体里一个控件的状态和text值。可是线程开启后主窗体不能动,其他控件的状态也是在这个线程结束后才改变的,并不是随着程序运行动态改变的。请问这是怎么回事?难道子线程操作主线程的控件要等线程结束后才可以,还有在子线程运行时主窗体为什么是假死状态,不能操作? private void PlayButton_Click(object sender, EventArgs e)
{
TransmitThread = new Thread(new ThreadStart(TransmitThreadMethod));
TransmitThread.IsBackground = true;
TransmitThread.Start();
}
private void TransmitThreadMethod()
{
MethodInvoker mi = new MethodInvoker(StupTransmit);
));
this.BeginInvoke(mi);
}
/// <summary>
/// 数据传输方法
/// </summary>
private void StupTransmit()
{
PlayButton.Enabled = false;
.... 这里边循环对主窗体控件属性改变的代码。
...... }
{
TransmitThread = new Thread(new ThreadStart(TransmitThreadMethod));
TransmitThread.IsBackground = true;
TransmitThread.Start();
}
private void TransmitThreadMethod()
{
MethodInvoker mi = new MethodInvoker(StupTransmit);
));
this.BeginInvoke(mi);
}
/// <summary>
/// 数据传输方法
/// </summary>
private void StupTransmit()
{
PlayButton.Enabled = false;
.... 这里边循环对主窗体控件属性改变的代码。
...... }
所以在2.0中该为必须使用委托方式来访问控件你可以需要使用异步的方法来操作 就不会有主线程假死状态了例如:
th1 = new Thread(new ThreadStart(FunInvo));
th1.IsBackground = true;
…………
private void FunInvo()
{
MethodInvoker mi = new MethodInvoker(FunInvoFunt);
//在窗体上调用 BeginInvoke
this.BeginInvoke(mi);
Thread.Sleep(300) ;
}private void FunInvoFunt()
{
//ToDo yourwork Here
}
th1 = new Thread(new ThreadStart(FunInvo));
th1.IsBackground = true;
…………
private void FunInvo()
{
MethodInvoker mi = new MethodInvoker(FunInvoFunt);
//在窗体上调用 BeginInvoke
this.BeginInvoke(mi);
Thread.Sleep(300) ;
}private void FunInvoFunt()
{
//ToDo yourwork Here
}
{
if (TransmitInfo.InvokeRequired)
{
MyInfoInvoke m = new MyInfoInvoke(WriteTransmitInfo);
this.Invoke(m, new object[] { info });
}
else
{
TransmitInfo.Text = info;
}
}可是主界面还是假死状态!!!
{
if (TransmitInfo.InvokeRequired)
{
MyInfoInvoke m = new MyInfoInvoke(WriteTransmitInfo);//??递归调用?
this.Invoke(m, new object[] { info });
}
else
{
TransmitInfo.Text = info;
}
}
{
if(this.InvokeRequired)
{
this.Invoke(new DlgateText(UpdateText), new object[]{text});
Thread.Sleep(500) ;
}
else
{
yourTextBox.Text = text;
}
}
……我刚才可能看走眼了 因该这么写 估计lz也是这样写的吧?
{
TransmitThread = new Thread(new ThreadStart(TransmitThreadMethod));
TransmitThread.IsBackground = true;
TransmitThread.Start();
}
private void TransmitThreadMethod()
{
MethodInvoker mi = new MethodInvoker(StupTransmit);
));
this.BeginInvoke(mi);
}
/// <summary>
/// 数据传输方法
/// </summary>
private void StupTransmit()
{
PlayButton.Enabled = false;
.... 这里边循环对主窗体控件属性改变的代码。
...... } 从你的代码看不出多线程的用途与必要,其结果肯定是主窗体处于假死状态
假设线程只执行一次用委托即可 private void TransmitThreadMethod()
{
MethodInvoker mi = new MethodInvoker(StupTransmit);
));
this.BeginInvoke(mi);
}
TransmitThreadMethod()这个方法只执行一次就报废了,结果是异步委托切换到UI线程
UI线程工作
private void StupTransmit()
{
PlayButton.Enabled = false;
.... 这里边循环对主窗体控件属性改变的代码。
...... }
这里面的循环都是在UI线程进行,就如同一个单线程,程序不假死么?
不过感觉这不是解决的根本之道!还得请高手解决一下
{
StupTransmit();
}