如何让多线程暂停后再重启?

jshzp 2011-09-28 09:19:27
窗体中启动多线程t,执行方法method,方法中满足某个条件后,线程自己暂停;当用户点击按钮后,继续执行线程。注意是继续执行线程,不是另外启动线程。代码如下:

public partial class Form1 : Form
{

Thread t;
public delegate void delegateM(int i);
delegateM dm;

public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
dm = m;
t = new Thread(Method);
t.Start();
}

void Method()
{
try
{
int i;
cnt: i = 0;
while (i < 300)
{
Thread.Sleep(10);
i++;
this.Invoke(dm, new object[] { i });//跨线程刷新窗体标题
Application.DoEvents();
}
Thread.Sleep(-1);//线程暂时停止
goto cnt;
}
catch
{ }
}

void m(int i)
{
this.Text = i.ToString();
}

private void button1_Click(object sender, EventArgs e)
{
try
{
t.Resume();//继续执行线程
}
catch
{ }
}
}

调试发现,上述代码达不到预期目的。应该怎么修改呢?谢谢!
...全文
556 27 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
潇洒王子 2011-09-29
  • 打赏
  • 举报
回复
看了各位大大的回复,看来我还得继续学习
0xAAFF 2011-09-29
  • 打赏
  • 举报
回复
我的想法就是定义一个public的bool值,比如:IsRun=true; 然后 线程sleep多少秒后 判断IsRun是否允许运行 如果不允许 再次休眠....
jshzp 2011-09-29
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 mabaolin 的回复:]
9楼程序不一定是lz想要得。如果lz想要得是线程执行到某个位置,等待一个信号或某个事件在继续执行的话,用autoresetevent,manualresetevent。 Monitor.wait
等都可以。
AutoResetEvent ev = new AutoResetEvent (false);
public void Do()
{
//do sth;
ev.waiton……
[/Quote]
你说得很明确,谢谢!
zhoucong1020 2011-09-29
  • 打赏
  • 举报
回复
用AutoResetEvent或者ManualResetEvent都可以,需要using System.Threading;

public partial class Form1 : Form
{

Thread t;
public delegate void delegateM(int i);
delegateM dm;

AutoResetEvent are;

public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
are = new AutoResetEvent(false);

dm = m;
t = new Thread(Method);
t.Start();
}

void Method()
{
try
{
int i;
cnt: i = 0;
while (i < 300)
{
Thread.Sleep(10);
i++;
this.Invoke(dm, new object[] { i });//跨线程刷新窗体标题
Application.DoEvents();
}
are.WaitOne();//线程暂时停止
goto cnt;
}
catch
{ }
}

void m(int i)
{
this.Text = i.ToString();
}

private void button1_Click(object sender, EventArgs e)
{
try
{
are.Set();//继续执行线程
}
catch
{ }
}
}
jshzp 2011-09-29
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 mabaolin 的回复:]
另受教了,还真不知道c#中有goto呢
[/Quote]
呵呵,其实我也不知道,只是对FORTRAN、PASCAL这些语言很熟悉,习惯goto过去
salecn 2011-09-29
  • 打赏
  • 举报
回复
来学习一下!
mabaolin 2011-09-29
  • 打赏
  • 举报
回复
另受教了,还真不知道c#中有goto呢
mabaolin 2011-09-29
  • 打赏
  • 举报
回复
9楼程序不一定是lz想要得。如果lz想要得是线程执行到某个位置,等待一个信号或某个事件在继续执行的话,用autoresetevent,manualresetevent。 Monitor.wait
等都可以。
AutoResetEvent ev = new AutoResetEvent (false);
public void Do()
{
//do sth;
ev.waitone();//大小写自己调
// do sth;
}

button-click()
{
ev.set();
}
liusahara 2011-09-29
  • 打赏
  • 举报
回复
xuexuexixixixix
机器人 2011-09-28
  • 打赏
  • 举报
回复
所谓的暂停,再继续 说白了就是一个flag

// 按钮控制全局标志suspend 为true还是false
private bool suspend = false;

...
int i = 0;
while (i < 300)
{
if (!suspend)
{
i++;
this.Invoke(dm, new object[] { i });//跨线程刷新窗体标题
}
Thread.Sleep(100); //就算没有暂停也适当等待,否则窗体无响应,直接显示300
// Application.DoEvents(); 没用的语句
}
// 后面的goto也没啥用。


当suspend=true时,while里就只执行Thread.Sleep
Icedmilk 2011-09-28
  • 打赏
  • 举报
回复
DoEvents的作用是处理消息队列中积累的消息,只有在主线程忙的时候才需要调用

你的method是跑在子线程上,并没有导致主线程忙
jshzp 2011-09-28
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 sp1234 的回复:]
呵呵但愿你能明白线程“暂停”!不过我想你得到的只是“阻塞”的结果。
[/Quote]
能细说下吗?或者指点点儿资料,我看看,谢谢!
jshzp 2011-09-28
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 icedmilk 的回复:]
引用 11 楼 icedmilk 的回复:

轮空不是你所说的空的运转
轮空的意思是,线程主动放弃他应得的时间片,直到他得到了足够的资源(或达到了某些条件)
[/Quote]
谢谢,我明白了
  • 打赏
  • 举报
回复
呵呵但愿你能明白线程“暂停”!不过我想你得到的只是“阻塞”的结果。
jshzp 2011-09-28
  • 打赏
  • 举报
回复
回11楼:
“另外你那个DoEvents不是用在主线程上,没有任何意义”,是吗?能具体说下吗?我理解DOEvents就是让其它线程处理消息,为什么只是用于主线程中呢?谢谢
线程重启的问题基本清楚了,应该就是你和3、4楼所说的,明天我再仔细看下MSDN的说法
Icedmilk 2011-09-28
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 icedmilk 的回复:]

轮空不是你所说的空的运转
轮空的意思是,线程主动放弃他应得的时间片,直到他得到了足够的资源(或达到了某些条件)
[/Quote]
Icedmilk 2011-09-28
  • 打赏
  • 举报
回复
轮空是你所说的空的运转
轮空的意思是,线程主动放弃他应得的时间片,直到他得到了足够的资源(或达到了某些条件)

另外你那个DoEvents不是用在主线程上,没有任何意义

        private void MainForm_Load(object sender, EventArgs e)
{
new Thread(method).Start();
}
private AutoResetEvent threadEvent = new AutoResetEvent(false);
private void button1_Click(object sender, EventArgs e)
{
threadEvent.Set();
}
void Method()
{
try
{
int i;
cnt: i = 0;
while (i < 300)
{
Thread.Sleep(10);
i++;
this.Invoke(dm, new object[] { i });//跨线程刷新窗体标题
}
threadEvent.WaitOne();
goto cnt;
}
catch
{ }
}
}
jshzp 2011-09-28
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 sp1234 的回复:]
重新修改你的“设计”吧。不要弄一个无休止的线程。可以类似这样:

C# code
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void Form1……
[/Quote]
谢谢回复!我发帖的目的不是为了实现一楼代码中的那个事物逻辑,而是为了弄明白怎么暂停、重启线程。
  • 打赏
  • 举报
回复
重新修改你的“设计”吧。不要弄一个无休止的线程。可以类似这样:
    public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
tmr.Elapsed += new System.Timers.ElapsedEventHandler(tmr_Elapsed);
tmr.Start();
}

void tmr_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
i++;
if (i >= 300)
i = 0;
this.BeginInvoke(new Action(() => { m(i); }));
}

int i;
System.Timers.Timer tmr = new System.Timers.Timer(10);

void m(int i)
{
this.Text = i.ToString();
}

private void button1_Click(object sender, EventArgs e)
{
tmr.Enabled = !tmr.Enabled;
}


}
jshzp 2011-09-28
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 fangxinggood 的回复:]
Thread.Sleep 就是节约CPU啊
[/Quote]
谢谢!sleep之后,让线程继续运行,用什么方法?
加载更多回复(7)

111,094

社区成员

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

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

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