3

I've got a class like this:

public class SecondaryThreadClass
{
    private string str;

    public SecondaryThreadClass ()
    {
    }

    ~SecondaryThreadClass(){
        Console.WriteLine("Secondary class's instance was destroyed");
    }

    public void DoJobAsync(){
        new Thread(() => {
//      this.str = "Hello world";
//      Console.WriteLine(this.str);

            Console.WriteLine("Hello world");
        }).Start();
    }
}

When I uncomment those two lines and comment Console.WriteLine("Hello world"); instead my destructor never gets called. So it appears that if I use "this" inside a secondary-thread method my object doesn't get collected. The caller's code is here:

    public override void ViewDidLoad ()
    {
        SecondaryThreadClass instance = new SecondaryThreadClass();
        instance.DoJobAsync();

        base.ViewDidLoad ();
    }

How can I make GC collect those objects? I'm using MonoTouch if it matters.

Edit:

    public void DoJobAsync(){
        new Thread(() => {
            this.str = "Hello world";
            Console.WriteLine(this.str);

    //      Console.WriteLine("Hello world");
            new Thread(() => {
                Thread.Sleep(2000);
                GC.Collect();
                GC.WaitForPendingFinalizers();
            }).Start();
        }).Start();
    }

This doesn't help either (timeout is needed to ensure that the first thread is finished before GC.Collect() is called).

Danchoys
  • 739
  • 1
  • 8
  • 14

1 Answers1

0

The following program works as expected on my system (which is NOT MONO).

What happens when you try it? If it doesn't work, then it looks like something weird in the implementation of Mono that you're using - which isn't much of an answer, but at least you know that it should work...

using System;
using System.Threading;

namespace Demo
{
    class Program
    {
        private static void Main(string[] args)
        {
            SecondaryThreadClass instance = new SecondaryThreadClass();
            instance.DoJobAsync();

            Console.WriteLine("Press a key to GC.Collect()");
            Console.ReadKey();

            instance = null;
            GC.Collect();

            Console.WriteLine("Press a key to exit.");
            Console.ReadKey();
        }
    }

    public class SecondaryThreadClass
    {
        private string str;

        public SecondaryThreadClass()
        {
        }

        ~SecondaryThreadClass()
        {
            Console.WriteLine("Secondary class's instance was destroyed");
        }

        public void DoJobAsync()
        {
            new Thread(() =>
            {
                this.str = "Hello world";
                Console.WriteLine(this.str);
            }).Start();
        }
    }
}

When are you expecting the GC to run? You're not expecting it to run before base.ViewDidLoad() returns are you?

Matthew Watson
  • 104,400
  • 10
  • 158
  • 276
  • Well, your code doesn't work in Mono's Console Application at least on Mac =( That's why I'm afraid it is a Mono's issue rather than mine. – Danchoys Mar 04 '13 at 10:39
  • Finally it worked with the "Release" build. Doesn't work in "Debug" mode. – Danchoys Mar 04 '13 at 10:45
  • 1
    The problem lies in the debugger as when started without debugging the program runs as intended. – Danchoys Mar 04 '13 at 10:51
  • The jitter and GC know that a debugger is attached and make the GC less aggressive. Because it is *really weird* to be debugging a program and suddenly your values start disappearing because the GC decided that it could clean up something that the program wasn't using anymore. – Eric Lippert Mar 04 '13 at 16:06