phil
phil

Reputation: 1446

Attribute constructor can't use console.writeline

So I was curious about what would happen if I applied the CallerMemberName attribute to an Attribute's constructor's parameter. Here is my very simple code.

class MyAttribute : Attribute
{
    public MyAttribute(string message, [CallerMemberName] string name = "none specified")
    {
        Console.WriteLine("\{message}: \{name}");
    }
}
[My("Program")]
class Program
{
    [My("Main")]
    static void Main(string[] args)
    {
        var MyAttribute = new MyAttribute("Inner");
        Console.ReadLine();
    }
}

I ran the code and nothing happened. So I put a breakpoint in the constructor to see if it would get hit. It did indeed. However, even though the Writeline call seems to be executing, nothing is showing up. Why not?

Also, the breakpoint did not get hit for the [My("Program")] attribute. Why not?

EDIT: According to SLaks's answer, there is a race condition could be fatal to the program. I changed the inside of the constructor to:

new Thread(() =>
{
    Thread.Sleep(1000);
    Console.WriteLine("\{message}: \{name}");
}).Start();

The Main and Inner attributes do print this way, but the Program attribute does not. Why is that?

Upvotes: 1

Views: 1041

Answers (1)

SLaks
SLaks

Reputation: 887415

This is a bug in the CLR loader.

If you run with the VS hosting process enabled and call Console.WriteLine() in the constructor of an attribute applied to the Main() function, or (IIRC) the class containing it, you will trigger a reentrancy race condition in the Console, and the Console will be completely broken for the lifetime of that program.

Don't do that.

Upvotes: 6

Related Questions