首页 > 解决方案 > 未调用 Main(string[] args) 方法

问题描述

我正在使用 Visual Studio 2017。

每当我按下F5开始调试程序时,我注意到类中的Main(string[] args)方法Program没有被调用,即使里面的字段Program已经初始化,如下面的截图所示:

在此处输入图像描述

创建TcpClient实例并将其分配给相应的字段后,调试器永远不会命中我在Main(string[] args)方法上设置的断点。

可以肯定的是,我已将项目的启动对象设置为Program类。那并没有解决问题:

在此处输入图像描述

我错过了什么?

编辑:

我已经Console.WriteLine("Entering Main method...")在我的Main方法中添加了,但是当我开始调试时它没有打印到控制台。

TcpClient从字面上看,在创建实例之后没有任何事情发生(或者更确切地说,没有任何事情是立即可见的) ——没有抛出异常;程序不会自行终止;控制台保持空白。

编辑:

原来在TcpClient构造函数内部发生了崩溃。

标签: c#visual-studiovisual-studio-2017

解决方案


请记住,此时TcpClient(string, int)构造函数会打开一个新连接(doc):

初始化 TcpClient 类的新实例并连接到指定主机上的指定端口。
...
此构造函数创建一个新的 TcpClient 并对提供的主机名和端口号进行同步连接尝试。

如果我复制/粘贴您的代码(插入我自己RemoteServerIpAddressStringTcpClient. 如果此时我破坏了调试器,我可以看到它被卡在了System.Net.Sockets.Socket.DoConnect,它正在尝试连接到远程机器。

过了一会儿,它放弃了,抛出了一个异常,然后抛出了一个TypeInitializationException,这会破坏调试器。

这符合您的观察:

在创建 TcpClient 实例之后,实际上什么都没有发生(或者更确切地说,什么都没有立即可见)——没有抛出异常;程序不会自行终止;控制台保持空白。

此时,TcpClient仍在尝试连接。在它成功之前,该类型永远不会被初始化,并且在这种情况发生Main之前永远不会运行。如果你离开它足够长的时间,它可能会失败,就像我的一样。

如果我确保TcpClient连接到一个打开的端口,那么TcpClient构造函数会立即完成并Main运行。


在静态构造函数中做长时间运行的事情——尤其是网络相关的事情——是一个非常糟糕的主意。当一个类型被初始化时,CLR 需要获取一个锁,这会阻止其他类型被初始化,并可能导致死锁。

您可能想要构建方法TcpClient内部Main,或者将其构建为:

private static readonly TcpClient TcpClient = new TcpClient();

然后主要是:

TcpClient.Connect(...);

推荐阅读