Debug vs Release mode differences when storing a delegate in a hashtable
The following code demonstrates a difference in the behavior of the .NET runtime between debug and release mode. I'm running .NET 1.1 with SP1 on Server 2003, but this also happens on Win2k and XP. We've been seeing it for months, but it was finally isolated by a team in Samara.
The code demonstrates three ways to test if a delegate is stored in the hashtable. All work in debug mode, but the first fails in Release mode unless the Release mode code is running under a debugger.
Does anyone have experience with this problem? Or know if a fix is available already or coming in 2.0?
using
System;
using
System.Collections;
namespace
DelegatesBug
{
/// <summary>
///
Illustrates a difference in the Release and Debug mode
behavior of delegates that are
///
contained in a hashtable.
///
Creates a delegate around a method and adds the
delegate to a hashtable.
///
At that point, asking the hashtable if it contains a
new delegate around the same
///
method returns true in debug mode and false in release
mode. Running
the release
///
mode in the debugger returns true (the same result as
in debug mode)
/// </summary>
class DelegatesBug
{
[STAThread]
static
void
{
Test test =
new Test();
Hashtable hashtable =
new Hashtable();
TestDelegate td =
new
TestDelegate(test.Method);
hashtable.Add(td,
null);
td();
// if this call is commented out, release and debug
modes work the same
// the Contains call returns false in release mode with no debugger (Ctrl + F5). With
// debug mode or the
debugger enabled, it returns true.
Console.WriteLine("New delegate is contained in hashtable: "
+ hashtable.Contains(new
TestDelegate(test.Method)));
// comparing the two delegates returns true
foreach
(MulticastDelegate del
in hashtable.Keys)
Console.WriteLine("The delegate from hashtable.Keys equals td: "
+ del.Equals(td));
// asking the hashtable if it contains the original
delegate returns true
Console.WriteLine("td is contained in the hashtable: "
+ hashtable.Contains(td));
Console.ReadLine();
}
}
public
delegate
void
TestDelegate();
public
class Test
{
public
void Method()
{
}
}
}