Search code examples
c#visual-studiovisual-studio-2017

Main(string[] args) method not called


I am using Visual Studio 2017.

Whenever I press F5 to start debugging my program, I notice that the Main(string[] args) method inside the Program class is not called, even though the fields inside Program are initialized, as you can see from the screenshot below:

enter image description here

After creating a TcpClient instance and then assigning it to the corresponding field, the debugger never hits the breakpoint I have set on the Main(string[] args) method.

Just to be sure, I have set the startup object for my project to be the Program class. That did not fix the issue:

enter image description here

What am I missing?

EDIT:

I have added Console.WriteLine("Entering Main method...") inside my Main method, but it is not printed to the console when I start debugging.

Literally nothing (or rather, nothing immediately visible) happens after the TcpClient instance is created -- no exceptions thrown; the program doesn't self-terminate; the console stays blank.

EDIT:

Turns out a crash is occurring inside the TcpClient constructor.


Solution

  • Remember that the TcpClient(string, int) constructor opens a new connection, at that point (doc):

    Initializes a new instance of the TcpClient class and connects to the specified port on the specified host.
    ...
    This constructor creates a new TcpClient and makes a synchronous connection attempt to the provided host name and port number.

    If I copy/paste your code (inserting my own RemoteServerIpAddressString), then I see the application hang as it tries to construct the TcpClient. If I break the debugger at that point, I can see that it's stuck in System.Net.Sockets.Socket.DoConnect, which is trying to connect to the remote machine.

    After a while it gives up, throws an exception, and a TypeInitializationException gets thrown, which breaks the debugger.

    This matches your observation:

    Literally nothing (or rather, nothing immediately visible) happens after the TcpClient instance is created -- no exceptions thrown; the program doesn't self-terminate; the console stays blank.

    At this point, the TcpClient is still trying to connect. Until it succeeds, the type never gets initialized, and until this happens Main will never be run. If you leave it long enough it will probably fail, just as mine did.

    If I make sure that the TcpClient is connecting to a port which is open, then the TcpClient constructor completes straight away and Main runs.


    It's a very bad idea to do long-running things - especially network-y things - inside a static constructor. The CLR needs to acquire a lock when a type is being initialized, and this stops other types from being initialized, and can cause deadlocks.

    You probably want to either construct the TcpClient inside your Main method, or construct it as:

    private static readonly TcpClient TcpClient = new TcpClient();
    

    and then in main:

    TcpClient.Connect(...);