对线程很不理解。Control.Invoke

颤菊大师 2008-12-26 09:36:46
        /// <summary>
/// 线程。
/// </summary>
private Thread myThread;
public Form1()
{
InitializeComponent();
// Control.CheckForIllegalCrossThreadCalls = false;
}

private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("这是主线程");
}

private void ThreadTask()
{
int stp, newVal;
Random random = new Random();

if (this.progressBar1.InvokeRequired)
{
mythis m = new mythis(ThreadTask);
this.progressBar1.Invoke(m);
}

while (true)
{
stp = this.progressBar1.Step * random.Next(-1, 2);
newVal = this.progressBar1.Value + stp;
if (newVal > this.progressBar1.Maximum)
newVal = this.progressBar1.Maximum;
else if (newVal < this.progressBar1.Minimum)
newVal = this.progressBar1.Minimum;
this.progressBar1.Value = newVal;
Thread.Sleep(100);
}
}
delegate void mythis();
private void Form1_Load(object sender, EventArgs e)
{
myThread = new Thread(new ThreadStart(this.ThreadTask));
myThread.IsBackground = true;
myThread.Start();
}


出来的效果是main线程无限等待,然后进度条在不断跳动。就是除了button1无法按下,其他都达到效果了。请问怎么解决?
// Control.CheckForIllegalCrossThreadCalls = false;
这个方法我懂,可是不好。只是屏蔽错误。初学线程。
...全文
121 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
颤菊大师 2008-12-26
  • 打赏
  • 举报
回复
感谢flyjimi ,真的很谢谢。你的回答让我明悟好多好多。谢谢!
flyjimi 2008-12-26
  • 打赏
  • 举报
回复
另外说点,下面的代码最好是在判断this.InvokeRequired之后。
int stp, newVal;
Random random = new Random();

就是放到else里面。
if (this.InvokeRequired)
{
mythis m = new mythis(ThreadTask);
this.Invoke(m);
}else{
//...
}

flyjimi 2008-12-26
  • 打赏
  • 举报
回复
private void step(){

int stp, newVal;
Random random = new Random();

if (this.InvokeRequired)
{
mythis m = new mythis(step);
this.Invoke(m);
}else{
stp = this.progressBar1.Step * random.Next(-1, 2);
newVal = this.progressBar1.Value + stp;
if (newVal > this.progressBar1.Maximum)
newVal = this.progressBar1.Maximum;
else if (newVal < this.progressBar1.Minimum)
newVal = this.progressBar1.Minimum;
this.progressBar1.Value = newVal;
}

}

private void ThreadTask()
{

while (true)
{
step();
Thread.Sleep(100);
}
}


不好意思,说着说着,关键的地方忘改了。标红的。
flyjimi 2008-12-26
  • 打赏
  • 举报
回复
你的问题出在Thread.Sleep(100);是在UI线程调用的。
在ThreadTask()中,下面的代码导致while循环是在UI线程执行的。
即UI线程在不停的设置progressBar,然后Sleep()。
应该是让工作线程执行一些功能后,更新progressBar,然后Sleep()。
if (this.progressBar1.InvokeRequired)
{
mythis m = new mythis(ThreadTask);
this.progressBar1.Invoke(m);
}

参考下面这种方式。

private void step(){

int stp, newVal;
Random random = new Random();

if (this.InvokeRequired)
{
mythis m = new mythis(ThreadTask);
this.Invoke(m);
}else{
stp = this.progressBar1.Step * random.Next(-1, 2);
newVal = this.progressBar1.Value + stp;
if (newVal > this.progressBar1.Maximum)
newVal = this.progressBar1.Maximum;
else if (newVal < this.progressBar1.Minimum)
newVal = this.progressBar1.Minimum;
this.progressBar1.Value = newVal;
}

}

private void ThreadTask()
{

while (true)
{
step();
Thread.Sleep(100);
}
}

颤菊大师 2008-12-26
  • 打赏
  • 举报
回复
一样。
就是,进度条在滚动。而主窗体的线程似乎被占用?
CruelYoung123 2008-12-26
  • 打赏
  • 举报
回复
button1 无法按下?

在load事件中加入

Applicaton.DoEvent();

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧