问题:我应该怎么去回收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;
} }
}
我的解决方法:添加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;
} }
}
解决方案 »
- Mock 的问题。会MOCK 的同学进来帮我看看
- 【新手求助】C# winform 框架问题 复合控件问题
- 自定义控件问题
- 应用程序生成DLL的问题
- C#简单算术运算程序遇到索引越界问题,急!
- 求解datagridview 如何实现动态纵向合并单元格??
- 在window怎样实现LDAP?!!!!?!!!分不够再加!
- 如何做一个属性页面
- 怎么让自己写的类库在被调用时和.Net提供的一样,会自动显示出方法和方法中参数的注释?
- 请教高手:如何写网络录音机/留声机的程序!(分数可再加!)
- ORA-01460:转换请求无法实现或不合理
- 当困惑:委托,事件,多线程,线程同步混在一起以后,程序变成什么样子了?
//主线程方法类using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Data.SqlClient;namespace Demo
{
class Program
{
static SqlDataReader sdr = null;
static int num = 3;
static CopyMeterThreadPool pool = new CopyMeterThreadPool(num);
//信号量
static Semaphore sema = new Semaphore(num, num); static void Main(string[] args)
{
//Print();
try
{
SqlConnection conn = new SqlConnection("server=10.180.84.37;database=test1;uid=sa;pwd=agile");
SqlCommand cmd = new SqlCommand("select * from person_info", conn);
conn.Open();
sdr = cmd.ExecuteReader(); List<Person> list = new List<Person>();
//int j = 0;
while (sdr != null && sdr.Read())
{
Person person = new Person();
person.Name = sdr["name"].ToString();
list.Add(person);
}
Console.WriteLine("开始:" + DateTime.Now.Millisecond.ToString());
string tstr = DateTime.Now.Millisecond.ToString(); //初始化线程池
for (int i = 0; i < num; i++)
{
Thread th = new Thread(new ParameterizedThreadStart(Print));
th.Name = "线程池" + i.ToString(); pool.Push(th);
} for (int k = 0; k < list.Count; k++)
{
if (pool.Count > 0 && sema.WaitOne())
{
Thread t = (Thread)pool.Pop();
//封装线程对象和信号量
Test test = new Test(list[k], t, sema); t.Start(test);
}
} }
catch (Exception e)
{ Console.WriteLine(e.Message); }
finally
{ Console.WriteLine("结束:" + DateTime.Now.Millisecond.ToString());
//Console.ReadLine();
}
Thread.Sleep(5000);
Console.WriteLine("结束时间*****************************************" + DateTime.Now.Millisecond.ToString());
Console.ReadLine();
}
static void Print(object obj)
{
//sdr.Read();
Test test = (Test)obj;
bool flag = false;
while (!flag)
{
try
{ for (int i = 0; i < 20; i++)
{
string str = test.P.Name.ToString();
str += "AAA";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q";
str += "q"; Console.WriteLine("Print" + i.ToString() + str);
} Console.WriteLine("__________________________"); }
catch (Exception es)
{ }
finally
{
test.Sema.Release(); SimpleThread s = new SimpleThread(test.Thread);
//调用线程停止的方法,来触发线程停止时的事件
s.SetStop(); flag = true;
}
} } static void Print2()
{
for (int i = 50; i < 100; i++)
{
Console.WriteLine("Print" + i.ToString());
}
} static void Print()
{
Thread t = new Thread(new ThreadStart(Print2));
t.Start();
Console.WriteLine("线程开始");
//t.Abort();
//Console.WriteLine("线程终止");
if (t.IsAlive)
{
//t.Start();
//t.Abort();
if (t.ThreadState == ThreadState.Stopped)
{
Thread th = t;
th.Start();
} //Thread.CurrentContext.DoCallBack(new p(new Test().Print2));
Console.WriteLine("线程继续开始");
}
}
class Test
{ public void Print2()
{
for (int i = 50; i < 100; i++)
{
Console.WriteLine("Print" + i.ToString());
}
}
private Semaphore sema; public Semaphore Sema
{
get { return sema; }
set { sema = value; }
}
private Person p; internal Person P
{
get { return p; }
set { p = value; }
}
private Thread thread; public Thread Thread
{
get { return thread; }
set { thread = value; }
} public Test(Person per, Thread t, Semaphore se)
{
sema = se;
p = per;
thread = t;
} public Test(Person per)
{
p = per;
//sema = se;
} public Test()
{ } } class Person
{
private string name; public string Name
{
get { return name; }
set { name = value; }
}
}
}
}
最好通过位于运算来判断
用AutoRestEvent和WaitEventHandle来实现比较稳
AutoRestEvent这个类是用来处理多个线程等待的类,用set()来告知线程是否还需要等待,请问,这个我怎么来处理线程是否结束?我刚开始就是用这种方法,不行,不知道你能不能再指点一下。谢了。
使用AutoRestEvent会使线程进入等待状态,直到其它线程Reset了这个参数.
有很多情况会造成异常,且在finally之前退出执行线程
因为项目中其他地方用了ThreadPool,而我这个线程池是要初始化大小的,我初始化了TreadPool的大小,可能会影响到主程序ThreadPool的运行。
ms不像sun啊,要是java应该好点。开源。
呵呵,谢谢,我知道线程是GC去回收的,但是没有办法,程序的框架不是我设计搭建的,你说的我的设计得改,能说清楚点吗?错在什么地方。(我其实也知道用MS的东西就是绑着枷锁跳舞,没有办法,经理要求,虽然现在改为其他的实现,就是用SemaPhore来控制线程,其实也没有重用这个概念了。我只是想把我写了一半的代码继续写下去,看能不能实现。)再次谢谢!