自己创建的线程池,碰到一个问题,哪位大侠帮我看看

VistaKobe 2009-09-07 04:02:07
问题:我应该怎么去回收Stack<Thread>中的Thread?(怎么判断线程完成工作了?然后下一步进行回收)。
我的解决方法:添加Thread停止的事件(st.OnThreadStop += new SimpleThread.ThreadStop(st_OnThreadStop);),在SetStop方法中触发这个事件,这样处理不知道是我代码有问题还是怎么回事,不能实现Thread的重用。

下面贴代码:

线程池类:

using System;
using System.Collections.Generic;

using System.Text;
using System.Threading;

namespace Demo
{
//线程状态枚举
enum ThreadStatus { Running,Stop};

class CopyMeterThreadPool
{
Stack<Thread> _pool;

//线程池初始化大小
private int _num;


public CopyMeterThreadPool(int capability)
{
_num = capability;
_pool = new Stack<Thread>(capability);
}

//压栈
public void Push(Thread thread)
{
if (thread == null)
throw new ArgumentNullException("线程池的线程未初始化!");
lock (_pool)
{
//重新包装要处理的Thread
SimpleThread st = new SimpleThread(thread);

//注册事件
st.OnThreadStop += new SimpleThread.ThreadStop(st_OnThreadStop);

_pool.Push(thread);
}
}

//事件委托的回收线程方法
void st_OnThreadStop(object sender, ThreadEventArgs e)
{
if (e.Status == ThreadStatus.Stop)
{
Thread t = (Thread)sender;
Push(t);
Console.WriteLine("成功放入线程池!");
}
}

//出栈
public Thread Pop()
{
lock (_pool)
{
return _pool.Pop();
}
}

public int Count
{
get { return _pool.Count; }
}

}

//封装线程的类
class SimpleThread
{
private Thread thread;

public Thread Thread
{
get { return thread; }
set { thread = value; }
}
//声明委托和事件
public delegate void ThreadStop(object sender, ThreadEventArgs e);

public event ThreadStop OnThreadStop;


public SimpleThread(Thread t)
{
thread = t;
}

//问题的关键在这里
public void SetStop()
{
if (thread.ThreadState == ThreadState.Running)
{
thread.Abort();
if (OnThreadStop != null)
{
if (thread.ThreadState == ThreadState.Aborted)
{
//thread.;
OnThreadStop(thread, new ThreadEventArgs(ThreadStatus.Stop));
}
}
}

}

}
//参数类
class ThreadEventArgs:EventArgs
{
private ThreadStatus status;

internal ThreadStatus Status
{
get { return status; }
}

public ThreadEventArgs(ThreadStatus status)
: base()
{
this.status = status;
}

}
}






...全文
977 39 打赏 收藏 转发到动态 举报
写回复
用AI写文章
39 条回复
切换为时间正序
请发表友善的回复…
发表回复
24K純帥 2009-09-09
  • 打赏
  • 举报
回复
我也帮你顶顶
VistaKobe 2009-09-09
  • 打赏
  • 举报
回复
补充:其实我也不是说要钻牛角尖。呵呵,做个尝试而已。谢谢大家的支持!
VistaKobe 2009-09-09
  • 打赏
  • 举报
回复
[Quote=引用 35 楼 icansaymyabc 的回复:]
老兄哦,你这个线程池有一个原则性的错误:

  在 .NET 框架里,Thread 归框架管不归你管,一个 Thread 停止之后,根据人家的游戏规则就得等着 GC 在他高兴的时候回收。可是你却在这个废线程被回收之前(也许已经被回收了)将它 push 进栈,还打算稍后将它 pop 出来。你是要做废品收购站啊?我说的“身在屋檐下,还敢不低头”就这个意思你好像没领会到。

  在 .NET 里自制线程池不是不可以,但是有一个条件,就是池里的任何一个线程都不能停,一旦停下来,它就会在不可预测的时间被GC回收了。所以你的设计得改,从根本上改。
[/Quote]

呵呵,谢谢,我知道线程是GC去回收的,但是没有办法,程序的框架不是我设计搭建的,你说的我的设计得改,能说清楚点吗?错在什么地方。(我其实也知道用MS的东西就是绑着枷锁跳舞,没有办法,经理要求,虽然现在改为其他的实现,就是用SemaPhore来控制线程,其实也没有重用这个概念了。我只是想把我写了一半的代码继续写下去,看能不能实现。)再次谢谢!
icansaymyabc 2009-09-09
  • 打赏
  • 举报
回复
[Quote=引用 36 楼 vistakobe 的回复:]
....
你说的我的设计得改,能说清楚点吗?错在什么地方
....
[/Quote]

天,这还要问哪?
我都说得这么明白了你还不知道错在哪儿?

你错在试图利用一个即将(或已经)被GC销毁的对象。

举个简单的例子,就是你试图聘用一个死囚,他可能随时(或已经)被执行死刑了。你还试跟他签劳动合同,并给他分配工作。他能够为你干活吗?

cysccnu 2009-09-08
  • 打赏
  • 举报
回复
先开两个线程,一个线程用来实现多线程,或者线程池,另一个线程执行主函数,用join方法等待前一个线程完了再执行。
gouhs 2009-09-08
  • 打赏
  • 举报
回复
走错了,全是高手
icansaymyabc 2009-09-08
  • 打赏
  • 举报
回复
身在屋檐下,你居然还敢不低头——唯一的结果就是头破血流。

你既然选择了 .NET 框架,你就尊重一下人家的游戏规则好了。人家明明有 ThreadPool 你不用,要自己去回收 Thread,真想得出来呀你。
yetxr 2009-09-08
  • 打赏
  • 举报
回复
顶顶吧,不会·
zyy19880524 2009-09-08
  • 打赏
  • 举报
回复
大家一起来接分......哈
icansaymyabc 2009-09-08
  • 打赏
  • 举报
回复
老兄哦,你这个线程池有一个原则性的错误:

在 .NET 框架里,Thread 归框架管不归你管,一个 Thread 停止之后,根据人家的游戏规则就得等着 GC 在他高兴的时候回收。可是你却在这个废线程被回收之前(也许已经被回收了)将它 push 进栈,还打算稍后将它 pop 出来。你是要做废品收购站啊?我说的“身在屋檐下,还敢不低头”就这个意思你好像没领会到。

在 .NET 里自制线程池不是不可以,但是有一个条件,就是池里的任何一个线程都不能停,一旦停下来,它就会在不可预测的时间被GC回收了。所以你的设计得改,从根本上改。
VistaKobe 2009-09-08
  • 打赏
  • 举报
回复
[Quote=引用 30 楼 aimeast 的回复:]
这样的底层,最好跟ms学学是怎么实现的。

要不然,我敢保证,你的这个池子完成后,不到一个月就能发现一大堆的问题。
[/Quote]

ms不像sun啊,要是java应该好点。开源。
aimeast 2009-09-08
  • 打赏
  • 举报
回复
这样的底层,最好跟ms学学是怎么实现的。

要不然,我敢保证,你的这个池子完成后,不到一个月就能发现一大堆的问题。
VistaKobe 2009-09-08
  • 打赏
  • 举报
回复
第一次出现在推荐区。希望有大侠能帮忙。谢谢推荐的xdjm。
simonllf 2009-09-08
  • 打赏
  • 举报
回复
少接触。。没看到MM。。
snoopy281 2009-09-08
  • 打赏
  • 举报
回复
VistaKobe 2009-09-08
  • 打赏
  • 举报
回复
补充,主程序中用到了ThreadPool。呵呵
VistaKobe 2009-09-08
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 icansaymyabc 的回复:]
身在屋檐下,你居然还敢不低头——唯一的结果就是头破血流。

你既然选择了 .NET 框架,你就尊重一下人家的游戏规则好了。人家明明有 ThreadPool 你不用,要自己去回收 Thread,真想得出来呀你。
[/Quote]

因为项目中其他地方用了ThreadPool,而我这个线程池是要初始化大小的,我初始化了TreadPool的大小,可能会影响到主程序ThreadPool的运行。
LutzMark 2009-09-08
  • 打赏
  • 举报
回复
Abort一直是不被推荐使用的
有很多情况会造成异常,且在finally之前退出执行线程
Mike老羊 2009-09-08
  • 打赏
  • 举报
回复
要不JOB掉
VistaKobe 2009-09-08
  • 打赏
  • 举报
回复
[Quote=引用 33 楼 cysccnu 的回复:]
先开两个线程,一个线程用来实现多线程,或者线程池,另一个线程执行主函数,用join方法等待前一个线程完了再执行。
[/Quote]

我们这个程序工作方式不是你说的这种,而是类似于线程池中有线程池(大体可以这样理解,呵呵)。
加载更多回复(18)

110,536

社区成员

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

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

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