P D*_*ddy 7 .net multithreading
我是否需要保护Thread垃圾收集器中的对象?包含该线程运行的函数的对象怎么样?
考虑一下这个简单的服
class Server{
readonly TcpClient client;
public Server(TcpClient client){this.client = client;}
public void Serve(){
var stream = client.GetStream();
var writer = new StreamWriter(stream);
var reader = new StreamReader(stream);
writer.AutoFlush = true;
writer.WriteLine("Hello");
while(true){
var input = reader.ReadLine();
if(input.Trim() == "Goodbye")
break;
writer.WriteLine(input.ToUpper());
}
client.Close();
}
}
static void Main(string[] args){
var listener = new TcpListener(IPAddress.Any, int.Parse(args[0]));
listener.Start();
while(true){
var client = listener.AcceptTcpClient();
var server = new Server(client);
var thread = new Thread(server.Serve);
thread.Start();
}
}
Run Code Online (Sandbox Code Playgroud)
我应该将我的线程对象包装在某种静态集合中,以防止它们被垃圾收集器扫除吗?
据推测,如果Thread对象本身保持活动状态,那么该Server对象将存在,因为该线程持有对委托的引用,该委托持有对目标对象的引用.或者可能收集线程对象本身,但实际线程继续运行.现在该Server对象正在进行收集.如果它试图访问其字段会发生什么?
垃圾收集使我的头旋转了一些时间.我很高兴我通常不必考虑它.
考虑到潜在的问题,我想相信垃圾收集器足够聪明,当线程本身仍在执行时不能收集线程对象,但我找不到任何文档说明.反射器在这方面没什么帮助,因为很多Thread类在不出所料的情况下都是在MethodImplOptions.InternalCall函数中实现的.而且我宁愿不通过我过时的旧SSCLI副本来寻找答案(因为这是一个痛苦,因为它不是一个肯定的答案).
这很简单.真正的执行线程不是Thread对象.该程序在真正的Windows线程中执行,无论.NET垃圾收集器对您的Thread对象执行什么操作,它都会保持活动状态.所以对你来说是安全的; 如果只是希望程序继续运行,则不需要关心Thread对象.
另请注意,您的线程在运行时不会被收集,因为它们实际上属于应用程序"根".(Roots - 垃圾收集器知道什么是活着的.)
更多细节:托管的Thread对象可以通过Thread.CurrentThread- 这类似于全局静态变量而不会被收集.正如我之前所写:任何已启动并且现在正在执行任何代码(甚至在.NET之外)的托管线程都不会丢失其Thread对象,因为它与"根"紧密相连.
| 归档时间: |
|
| 查看次数: |
3748 次 |
| 最近记录: |