1

This code behaves strangely. If I comment the line

        Process[] processlist = Process.GetProcesses();

then it works as expected. I see a 'test' message every 2 seconds. If I leave this line, it will print 2-3 'test' messages then stop. What am I doing wrong?

static void processTimerCallback(object x)
    {
        try
        {
            Process[] processlist = Process.GetProcesses();
        }
        catch
        {
        }
        Console.WriteLine("test");
    }

static void Main(string[] args)
{
    System.Threading.Timer processTimer = new System.Threading.Timer(new   TimerCallback(processTimerCallback), null, 2000, 2000);
    Application.Run(form = new MainForm());
}
user957455
  • 23
  • 2
  • check for exception, may be this behaviour is becuase of some error – Waqas Sep 21 '11 at 16:56
  • I am not able to reproduce this behavior given just this code. Is an exception being thrown? What does MainForm do? – vcsjones Sep 21 '11 at 16:56
  • Yeah, this would happen with an exception. I guess put Console.WriteLine("cunch") in the catch block and you'll know. – Kell Sep 21 '11 at 17:01
  • Even if there was an exception, Console.WriteLine would still happen. There is no exception caught. – user957455 Sep 21 '11 at 17:07
  • I replaced Application.Run with Thread.Sleep(50000), so there is no mention of MainForm now. It still behaves like that. – user957455 Sep 21 '11 at 17:07
  • possible duplicate of [Why does a System.Timers.Timer survive GC but not System.Threading.Timer?](http://stackoverflow.com/questions/4962172/why-does-a-system-timers-timer-survive-gc-but-not-system-threading-timer) – Hans Passant Sep 21 '11 at 18:26

2 Answers2

2

I linked to another answer that explains the problem. In a nutshell, the problem is not with the Process class, it is with the timer. It is a local variable of your Main() method, not sufficient to keep the garbage collector convinced that the timer object is still in use. Nobody can repro the problem from your code snippet because the garbage collector won't run often enough.

The difference between the Debug and Release build is the way the jitter reports the life-time of local variables. When a debugger is attached, it reports it life for the entire method body. That makes debugging easy.

Two basic fixes for this problem. The insight one:

static void Main(string[] args)
{
    System.Threading.Timer processTimer = new System.Threading.Timer(new   TimerCallback(processTimerCallback), null, 2000, 2000);
    Application.Run(form = new MainForm());
    GC.KeepAlive(processTimer);
}

And the practical one:

static System.Threading.Timer processTimer;

static void Main(string[] args)
{
    processTimer = new System.Threading.Timer(new   TimerCallback(processTimerCallback), null, 2000, 2000);
    Application.Run(form = new MainForm());
}
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
0

I tried the program once as a console app and once as a windows forms app. It didn't crash on my machine, but I'm logged in as an administrator. Maybe you access a process you are not allowed to?

The code is a bit strange because you access the Console within a windows application. And I miss the attribute STAThread before the Main method (however I tried without, it didn't crash).

slfan
  • 8,950
  • 115
  • 65
  • 78
  • I created a new Console project and I couldn't reproduce this. So I converted to a Windows project. Still didn't happen. But then I switched to Release mode. In release mode this crashes. Replacing Console with Trace and adding STAThread doesn't help. – user957455 Sep 21 '11 at 17:08
  • I tested release mode as well. No crash. I still think it might be some security problem. Can you try on anohter machine? Do you have any entries in the event log? – slfan Sep 21 '11 at 17:26
  • No entries in the log about this. The same code works in Debug mode, so can't be because of security. I've created a new Windows app, and pasted that code and still happens. There is no exception; the application keeps running, just something happens and Console.WriteLine never gets called. I've tested this on .NET 4 and 3.5. There must be something wrong with my machine, .NET installation, etc., if you say you can't reproduce this. – user957455 Sep 21 '11 at 17:41
  • Since the application keeps running, why don't you pause execution in the debugger, and see where the "next statement" pointer is in each of the threads. If there is some kind of deadlock, that will help you find it. – phoog Sep 21 '11 at 17:51