需求:多线程停止后点开始按钮能再次开始。多线程 OnNumberClear();//引发完成事件 threads[i].Abort(); 线程都销毁了,不能重启了,怎么解决?试图不销毁线程,让while退出循环但是失败,请教有何好办法?
private void btnTest_Click(object sender, EventArgs e)
{
Program();
Action();
}
public void test()
{
while (true)
{
if (this.InvokeRequired)
{
Monitor.Enter(this);//锁定,保持同步 .....//代码省略 if (......)
{
OnNumberClear();//引发完成事件
}
}
Monitor.Exit(this);//取消锁定
Thread.Sleep(5);
}
}
private void run()
{
test();
}
public void Program()
{
maxThread = 50;
threads = new Thread[maxThread];
for (int i = 0; i < maxThread; i++)
{
Thread t = new Thread(run);
t.Name = string.Format("{0}", i);
t.IsBackground = true;//程序关闭之后,线程关闭
threads[i] = t;
}
} public void OnNumberClear()
{
for (int i = 0; i < maxThread; i++)
{
threads[i].Abort();
}
}
public void Action()
{
for (int i = 0; i < maxThread; i++)
{
threads[i].Start();
}
}
private void btnTest_Click(object sender, EventArgs e)
{
Program();
Action();
}
public void test()
{
while (true)
{
if (this.InvokeRequired)
{
Monitor.Enter(this);//锁定,保持同步 .....//代码省略 if (......)
{
OnNumberClear();//引发完成事件
}
}
Monitor.Exit(this);//取消锁定
Thread.Sleep(5);
}
}
private void run()
{
test();
}
public void Program()
{
maxThread = 50;
threads = new Thread[maxThread];
for (int i = 0; i < maxThread; i++)
{
Thread t = new Thread(run);
t.Name = string.Format("{0}", i);
t.IsBackground = true;//程序关闭之后,线程关闭
threads[i] = t;
}
} public void OnNumberClear()
{
for (int i = 0; i < maxThread; i++)
{
threads[i].Abort();
}
}
public void Action()
{
for (int i = 0; i < maxThread; i++)
{
threads[i].Start();
}
}
如何重建?
就重新Program()一次就重建了,具体可以你还要调整下代码
如何重建?
就重新Program()一次就重建了,具体可以你还要调整下代码
我都试过了,就重新Program()也没用的,应该怎么调整
如何重建?
就重新Program()一次就重建了,具体可以你还要调整下代码
我都试过了,就重新Program()也没用的,应该怎么调整
你的排他锁出问题了。
OnNumberClear();//引发完成事件
这句话把他自己干掉了,后来线程创建成功了,但是无法获取排他锁,所以你感觉没有成功,要在OnNumberClear方法之前先释放排他锁
如何重建?
就重新Program()一次就重建了,具体可以你还要调整下代码
我都试过了,就重新Program()也没用的,应该怎么调整
你的排他锁出问题了。
OnNumberClear();//引发完成事件
这句话把他自己干掉了,后来线程创建成功了,但是无法获取排他锁,所以你感觉没有成功,要在OnNumberClear方法之前先释放排他锁还是不行,排它锁在onNumberClear方法前释放,就会继续执行循环语句(每次循环collectModel.RemoveAt(0);//删除ArrayList中的元素)报错:索引超出范围。必须为非负值并小于集合大小
如何重建?
就重新Program()一次就重建了,具体可以你还要调整下代码
我都试过了,就重新Program()也没用的,应该怎么调整
你的排他锁出问题了。
OnNumberClear();//引发完成事件
这句话把他自己干掉了,后来线程创建成功了,但是无法获取排他锁,所以你感觉没有成功,要在OnNumberClear方法之前先释放排他锁还是不行,排它锁在onNumberClear方法前释放,就会继续执行循环语句(每次循环collectModel.RemoveAt(0);//删除ArrayList中的元素)报错:索引超出范围。必须为非负值并小于集合大小这是你没贴出来的代码问题了,我试了,本来的问题应该是在排他锁上,建议你先把本线程之外的线程全部终止,然后再把排他锁释放,然后将本线程终止
重新启动Start就可以
看你用threads[i]记住要回收啊
例子:http://www.jb51.net/article/34804.htm
至少BackgroundWorker开始、暂停、停止,功能不错的,停止了还能再重新开始,7楼说的重新new一下就能重新开始纯属扯淡,线程Abort()了是不能再恢复的,thread要实现重新开始貌似只能让线程暂停,做出一种停止的假象。反正网上找了很多也没找到用thread很完美的方案。
bool runFlg = true;
bool isContinue = true; System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(
(obj) =>
{
autoWait.WaitOne(System.Threading.Timeout.Infinite, false);
while (runFlg)
{
if (!isContinue) break;
//To Do Something
}
}));
//按钮暂停事件中让线程暂停(线程挂起)
isContinue = false; //按钮开始事件中让线程重新开始
autoWait.Set();
isContinue = true; //销毁线程时
runFlg = false;
thread.Abort();上面只是一个伪代码,楼主实现的时候,需要调整,比如autoWait变成全局变量等。
至少BackgroundWorker开始、暂停、停止,功能不错的,停止了还能再重新开始,7楼说的重新new一下就能重新开始纯属扯淡,线程Abort()了是不能再恢复的,thread要实现重新开始貌似只能让线程暂停,做出一种停止的假象。反正网上找了很多也没找到用thread很完美的方案。
呵呵
ManualResetEvent .WaitOne();暂停
------------------------------------ManualResetEvent.set();
继续