本文介绍了为什么垃圾收集器不收集Tasks对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尤其是当没有实时线程引用它时.

我认为GC会考虑所有.net线程来查找引用...它是否也在其他地方检查引用?

让我们想象一下,我们在控制台应用程序中,实例调用了一个方法,该方法创建一个本地task1,然后应用task1.ContinueWith(task2)并返回到main,main do console.readline(). /p>

这时可能是task1已完成,task2仍未启动,GC可能已启动,并且没有线程引用task2.为什么task2无法获取GC?

说任务"时可能使用的单词不正确

using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication
{
    class Program
    {
        static void Launch()
        {
            var task1 = Task.Run(() => Thread.Sleep(60000))
            task1.ContinueWith(() =>  WriteToFile("Hi"));
        }

        static void Main(string[] args)
        {
            Launch();
            //At this point if a GC occurs which thread or static file has a reference to "()=>WriteTofile("Hi")" ?
            Console.ReadLine();
        }

有一个主线程在等待控制台,一个线程(可能来自线程池)正在运行Sleep.在睡眠完成之后,在WriteToFile线程启动之前,可能会发生GC,不是吗?

解决方案

task1的引用正在保存默认任务计划程序,(默认任务计划程序是静态的).

task1使延续保持活跃直到移交给它为止,才分配了任务计划程序(默认情况下在创建时为TaskScheduler.Current).

(请注意,这些可能不是唯一可能的根源,只是我从源代码中快速找到的根源)

especially when no live Thread reference it.

I thought GC goes thought all .net threads to find references... Does it check references in other places too?

EDIT: FOr instance let's imagine we are in a console app, the main calls a method that creates a local task1, then applies a task1.ContinueWith(task2) and returns to main, main do console.readline().

At this point it could be that task1 has finished, task2 still has not started a GC could start and no thread has a reference to task2. Why task2 doesn't get GC'ed?

EDIT2: Probably I'm not using the right words when saying "task"

using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication
{
    class Program
    {
        static void Launch()
        {
            var task1 = Task.Run(() => Thread.Sleep(60000))
            task1.ContinueWith(() =>  WriteToFile("Hi"));
        }

        static void Main(string[] args)
        {
            Launch();
            //At this point if a GC occurs which thread or static file has a reference to "()=>WriteTofile("Hi")" ?
            Console.ReadLine();
        }

There is the main thread waiting for the console, one thread (maybe from the threadpool) running the Sleep. Just after the Sleep is done, and before the WriteToFile thread start, a GC could happen, isn't it?

The reference to task1 is being held by the default task scheduler, (The default task scheduler is static).

The continuation is kept alive by task1 until it is handed off to it's assigned the task scheduler (TaskScheduler.Current at the time of creation by default).

(Note, these are likely not the only possible roots, just the ones I quickly found looking through the source)

这篇关于为什么垃圾收集器不收集Tasks对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-21 17:33