为什么 throw 会使我的程序崩溃,而 return 却不会?

发布于 2024-12-06 08:21:21 字数 1090 浏览 0 评论 0原文

我试图捕获异常,因为我的表单客户端无法在 Connect 回调中使用此方法建立与服务器的连接:

try
{
    client.EndConnect(async);
}
catch (Exception e)
{
    client.Close();

    return;
}

这工作正常,但此行为被封装到一个类中,因此我想调用 throw;< /code> 而不是 return; ,以便客户端类可以处理它,如下所示:

try
{
    client.Connect(host, port);
}
catch
{
    Console.WriteLine("Could not connect to: " + host + ":" + port.ToString());
}

那么为什么不直接调用 throw; 呢?好吧,由于某种原因,如果我调用 throw;throw new Exception(); 或基本上除 return; 之外的任何内容,程序都会很快失败。我真的不确定是什么原因造成的。我尝试删除 client.Close(); 以查看是否是问题所在,但没有任何结果。如果我不调用 return; 程序就会立即退出,不会出现错误。

有人知道这是怎么回事吗?

编辑:我不明白为什么我的投票率如此之低。我展示了如何尝试捕获这些异常,并询问为什么它们不能正常工作。我认为问题可能是(不确定,只是想出这个)因为在异步回调中,因为它是ThreadPool中的新线程,调用 throw; 不会执行任何操作,因为,因为它不是同步的,没有任何东西可以返回并且应用程序终止。即使有了这些知识,我也不确定如何解决这个问题,除非我在整个程序上放置某种 try-catch。

我认为解决方案可能只是坚持使用 return; 因为没有什么可以返回(由于该方法的异步回调性质),而是引发一个指示连接失败的事件。无论如何,非常感谢您的反对票并帮助我解决了这个问题。哦等等...

I am trying to catch exceptions for my form client not being able to establish a connection to a server with this in the Connect callback:

try
{
    client.EndConnect(async);
}
catch (Exception e)
{
    client.Close();

    return;
}

This works fine but this behavior is encapsulated in to a class so I want to call throw; instead of return; so that the client class can handle it instead, like so:

try
{
    client.Connect(host, port);
}
catch
{
    Console.WriteLine("Could not connect to: " + host + ":" + port.ToString());
}

So why not just call throw; then? Well, for some reason if I call throw;, throw new Exception();, or basically anything other than return; the program failsfast. I'm really not sure what's causing this. I tried removing client.Close(); to see if it was the problem but nothing. If I don't call return; the program just immediately exits with no error.

Anyone know what's going on here?

Edit: I do not understand why I am getting downvoted so much. I showed how I am attempting to catch these exceptions and am asking why they are not working properly. I think the problem may be (not sure, just came up with this) because within the asynchronous callback, because it is a new thread in the ThreadPool, calling throw; does not do anything because, because it is not synchronous, there is nothing to throw back to and the application dies. Even with this knowledge, I am not sure how to solve this problem unless I put some sort of try-catch on the entire program.

I suppose a solution could be just sticking with return; because there is nothing to throw back to (due to the asynchronous callback nature of the method) and instead raise an event indicating a failure of connection. Regardless, many thanks for the downvotes and helping me solve this problem. Oh wait...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

诗酒趁年少 2024-12-13 08:21:21

发生的情况是 EndConnect 没有与 BeginConnect 发生在同一线程上。当 EndConnect 抛出异常时,它会被工作线程的未处理异常处理程序捕获,该处理程序会快速失败(另一种选择是它会被忽略,并且您永远不会发现您的代码无法正常工作)。

您必须想出一种方法来告诉主窗体线程连接失败。

What's happening is that the EndConnect is not happening on the same thread as your BeginConnect. When EndConnect throws an exception, it is caught by the worker thread's unhandled exception handler, which fails fast (the other option is that it gets ignored and you never find out that your code isn't working).

You have to come up with a way to tell your main form thread that the connect failed.

单身狗的梦 2024-12-13 08:21:21

正如其他人指出的那样,您需要以一种或另一种方式捕获异常以避免程序终止。

有关如何“全局”执行此操作的一些想法,请参阅如何捕获 .NET 应用中的所有异常/崩溃 。这实际上是否是一个好主意取决于您的程序的具体需求...

与 WinForms 相关:

无法仅根据您的问题来判断,但如果这实际上是一个 WinForms 应用程序,您可能需要了解抛出异常的模态形式的行为存在差异,具体取决于调试器是否处于活动状态。假设我们有两种形式 - 第二个形式显示为第一个形式的模式子级:

  • 如果应用程序是通过调试器启动的,则第二个形式将关闭,并且堆栈展开一直到第一个形式的 catch 块(如果有) 。
  • 如果应用程序在调试器外部启动,则堆栈展开会在第二个窗体关闭并显示通用异常消息之前停止。第二种形式保持打开状态,第一种形式中的 catch 块永远不会到达。

As others have pointed out, you'll need to catch your exception one way or another to avoid program termination.

For some ideas on how you can do that "globally", see How to catch ALL exceptions/crashes in a .NET app. Whether this is actually a good idea depends on the specific needs of your program...

Relevant for WinForms:

Can't tell based on your question alone, but in case this is actually a WinForms application, you may need to be cognizant of the difference in behavior of modal forms that throw exceptions, depending on whether the debugger is active or not. Let's say we have two forms - the second one is shown as a modal child of the first one:

  • If application was started through debugger, second form is closed and and stack unwinding goes all the way to the first form's catch block (if any).
  • If application is started outside debugger, stack unwinding stops before second form is closed and generic exception message is displayed. The second form stays open and catch block in the first form is never reached.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文