var thread = new Thread(() => {
Thread.Sleep(10);
throw new Exception("Uh oh!");
});
thread.Start();
Thread.Sleep(100);
Console.WriteLine("Done!");
fails as expected.You can opt into unobserved task exceptions terminating the application if that's what you are looking for, and maybe subscribe to TaskScheduler.UnobservedTaskException event too: https://learn.microsoft.com/en-us/dotnet/api/system.threadin...
Notably, this is an issue in Go where a package might spawn a goroutine with uncaught panic, like dereferencing a nil which is common, and you have no recourse to this at all. Perhaps it did historically make sense in Go, but it continues to bite people and requires more careful vetting of the dependencies. Moreover, in type-safe memory-safe languages uncaught exception might be a perfectly fine thing to ignore.
When you fire and forget a task and it ends up throwing, GC will simply collect all the objects that no longer have GC roots, and the finally blocks will be ran, and finalizers will be called eventually on Gen2 GC if there are any - the standard library and most community abstractions that interact with manual memory management through interop or otherwise end up being watertight as a result of that.