25
votes

We have a Windows Form application that targets .Net Framework 4.0. After installing .Net Framework 4.5, the application starts crashing. We'll have to investigate the crashes and we'll most probably have to fix things on our side. But is there a setting we can turn on to keep the old behavior until we are ready to use .Net 4.5?


Update 07/12/2012: We found the breaking change that causes our application to crash: Given a System.Threading.Timer, when calling Dispose(WaitHandle) with an handle that has already been closed, then the Timer tries to signal the WaitHandle which throws an exception. The .Net 4.0 implementation of Timer was tolerant to that but 4.5 is not.

There is a bug on our side; we don't have any good reason to give it a closed handle so we'll just fix that...until we find another bug...

2
Are your projects set to '.NET framework 4.0'?Leon Cullens
@Sly I'm from .NET Framework compatibility Team. Could you send me a repro on netfx45compat at Microsoft dot com so that I could take a look?Varun
@Varun: The repro is what I wrote. Just pass a closed WaitHandle instance to the Dispose method or a Timer.Sylvain
@Sly Could you contact me on netfx45compat at Microsoft dot com?Varun
@Sly: you should post your update as an answer to this question.user7116

2 Answers

29
votes

But is there a setting we can turn on to keep the old behavior until we are ready to use .Net 4.5?

No. .NET 4.5 is an in-place replacement of .NET 4. When you install it, you're effectively running on the new framework.

In general, it should be completely backwards compatible, but there are a few breaking changes.

Unfortunately, this is going to mean that you (and everyone else) will need to test and fix problems on both frameworks if you want to support running on a machine with 4.5 installed and without 4.5 installed. Luckily, the breaking changes are typically all unusual, edge cases, so it's unlikely to impact most users in most scenarios.

6
votes

I discussed this over email with original question poster - "Sly". Thanks Sly for helping investigate. It turns out that .NET4 and .NET4.5 behave the same way for Dispose(waithandle) API. So this problem is potentially unrelated to .NET4.5.

    static void Main(string[] args)
    {
        System.Threading.Timer timer = new System.Threading.Timer(new System.Threading.TimerCallback(blah));
        System.Threading.EventWaitHandle eventWaitHandle = new System.Threading.EventWaitHandle(true, System.Threading.EventResetMode.ManualReset);

        eventWaitHandle.Dispose();
        System.Threading.Thread.Sleep(2000);
        timer.Dispose(eventWaitHandle);
    } 

    private static void blah(object state)
    {
        Console.WriteLine(40);
    }