90915
非同期タスクの未処理例外でプロセスを終了させる設定 ThrowUnobservedTaskExceptions が .NET6 で機能しません。  
.NET Framework 4.8 では機能していたのですが、.NET6 に移行してから機能しなくなりました。

App.config に以下のように設定しています。

```

    <configuration>
        <runtime>
            <ThrowUnobservedTaskExceptions enabled="true"/>
        </runtime>
    </configuration> 
    
```

.NET6 では他の場所に設定するのでしょうか。それともこの設定自体廃止されたのでしょうか？
CC BY-SA 4.0
2022-09-03T09:19:04.013
90910
2022-09-03T14:22:02.240
14817
question
.net
.NET6 で ThrowUnobservedTaskExceptions 設定が機能しない
[互換性に影響を与える変更点](https://docs.microsoft.com/ja-
jp/dotnet/core/compatibility/)にはそれらしい記述は見つけられませんでした。本当に書かれていないのか、それとももっと抽象的な表現に含まれてしまっているのかはわかりません。

ソースコードを見ると、実際問題、この機能はなくなっています。

[.NET Framework
4.6.2の`TaskExceptionHolder`ファイナライザー](https://github.com/microsoft/referencesource/blob/4.6.2/mscorlib/system/threading/Tasks/TaskExceptionHolder.cs#L94-L150)にはいろいろと処理をしていて、最後に

```

    // Now, if we are still unobserved and we're configured to crash on unobserved, throw the exception.
    // We need to publish the event above even if we're not going to crash, hence
    // why this check doesn't come at the beginning of the method.
    if (s_failFastOnUnobservedException && !ueea.m_observed)
    {
        throw exceptionToThrow;
    }
    
```

とあり、`s_failFastOnUnobservedException`変数はApp.configの値から設定されます。ファイナライザースレッドで投げられた例外は処理できずにプロセスが停止されるのでしょう。

それに対し、[.NET
5.0.0の`TaskExceptionHolder`ファイナライザー](https://github.com/dotnet/runtime/blob/v5.0.0/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TaskExceptionHolder.cs#L51-L70)は

```

    ~TaskExceptionHolder()
    {
        if (m_faultExceptions != null && !m_isHandled)
        {
            // We will only propagate if this is truly unhandled. The reason this could
            // ever occur is somewhat subtle: if a Task's exceptions are observed in some
            // other finalizer, and the Task was finalized before the holder, the holder
            // will have been marked as handled before even getting here.
    
            // Publish the unobserved exception and allow users to observe it
            AggregateException exceptionToThrow = new AggregateException(
                SR.TaskExceptionHolder_UnhandledException,
                m_faultExceptions);
            UnobservedTaskExceptionEventArgs ueea = new UnobservedTaskExceptionEventArgs(exceptionToThrow);
            TaskScheduler.PublishUnobservedTaskException(m_task, ueea);
        }
    }
    
```

ときれいさっぱり整理されています。

* * *

プロセスを終了させたいのであれば、[`<ThrowUnobservedTaskExceptions>`要素の解説](https://docs.microsoft.com/ja-
jp/dotnet/framework/configure-apps/file-
schema/runtime/throwunobservedtaskexceptions-
element#remarks)にもあるように[`TaskScheduler.UnobservedTaskException`イベント](https://docs.microsoft.com/ja-
jp/dotnet/api/system.threading.tasks.taskscheduler.unobservedtaskexception?view=net-6.0)からプロセスを終了すればいいのではないでしょうか？
CC BY-SA 4.0
2022-09-03T14:22:02.240
90915
2022-09-03T14:22:02.240
4236
90910
answer