【问题标题】:Throw inside Catch in C#在 C# 中抛出 Catch
【发布时间】:2018-11-18 05:25:58
【问题描述】:

昨天发现了一些东西,让我意识到我很可能仍然缺少关于 C# 的基本花絮。

我有一个无状态 Service Fabric 应用程序。我在主while循环中有一个try-catch。如果我在这个循环中抛出一个异常,它就会跳出 while 循环并且服务会有效地停止。如果我在 catch 子句中添加 throw,服务将重新启动。

    protected override async Task RunAsync(CancellationToken cancellationToken)
    {
        try
        {
            long iterations = 0;
            while (true)
            {
                cancellationToken.ThrowIfCancellationRequested();

                await Task.Delay(TimeSpan.FromSeconds(3), cancellationToken).ConfigureAwait(false);

                // Do stuff...

                if (iterations > 4) {
                    throw new Exception();
                } 

                ServiceEventSource.Current.ServiceMessage(this.Context, $"Working-{++iterations}");
            }
        }
        catch (Exception ex)
        {
            // Log stuff...
            throw;
        }
    }

有人可以解释为什么会这样,或者可以指导我到哪里得到答案吗?我找不到任何可以解释这种行为的东西。

编辑:它不是 Is there a difference between "throw" and "throw ex"? 的副本,因为据我所知,它没有解释我的问题,为什么该函数再次运行。该主题更多地是关于解释 throwthrow new 各自的堆栈跟踪之间的区别。

【问题讨论】:

  • 你能发布不同的替代代码吗?目前很难说出你在问什么。
  • 我的假设是程序的这一部分再次被包装在某个地方并抛出异常被转换为错误退出,而有效地返回被呈现为优雅关闭(因为异常中断了外部的执行线程while 循环,因此方法退出)
  • “我很可能仍然缺少有关 C# 的基本花絮”,我不会称其为“基本”,使用异步代码处理异常看起来很容易,但它非常微妙而不是微不足道实际上。

标签: c# throw rethrow


【解决方案1】:

根据您的描述,我们有两种选择:

  1. 您重新抛出异常,RunAsync Task 因该异常而失败
  2. 您不重新抛出异常,RunAsync Task 会正常完成(捕获的异常打破了 while 循环,因此方法退出)。

对于第一种情况,Service Fabric Stateless Service RunAsync doc 进一步详细说明了遇到异常时的行为,即从FabricException 派生的异常将导致重新启动,而其他异常要么是有意或意外的服务中止并导致其停止。

优雅完成逻辑上意味着服务成功执行完毕,将按照Service Fabric Reliable Services Lifecycle doc关闭。

【讨论】:

  • 啊,这样更有意义。我以为我误解了 C# 中的 throwing 和 re-throwing 的作用。难怪我找不到满意的答案。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-11
  • 2011-03-18
  • 2013-09-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多