Description
Description
Probably starting with the faster exceptions of .NET 9, in an application that provides an out-of-process COM server, when a method that has been called from the COM client throws an exception, the first of these exceptions raises the event AppDomain.CurrentDomain.UnhandledException
.
However, this happens only in some type of clients, my guess is clients that use IDispatch.
Reproduction Steps
-
Get the out-of-process COM example from https://github.com/dotnet/samples/tree/main/core/extensions/OutOfProcCOM.
-
Change the
ExeServer
project to use .NET9. -
In
Program.cs
of the projectExeServer
, inMain
, add these lines after the call ofTrace.Listeners.Add
:AppDomain.CurrentDomain.UnhandledException += (sender, e) => Trace.WriteLine($"CurrentDomain_UnhandledException: IsTerminating={e.IsTerminating}, {e.ExceptionObject}"); Trace.WriteLine($"Environment.Version is {Environment.Version}, Is64BitProcess is {Environment.Is64BitProcess}."); Trace.WriteLine($"DOTNET_LegacyExceptionHandling is '{Environment.GetEnvironmentVariable("DOTNET_LegacyExceptionHandling")}'.");
-
In
ExeServer.cs
, in the methoddouble IServer.ComputePi()
, add this line as second line:throw new OverflowException("This is not an actual overflow.");
-
In the project
ManagedClient
in the fileProgram.cs
, make these changes:-
Replace the line
var server = (IServer)obj;
withdynamic server = obj;
-
Replace these lines:
double pi = server.ComputePi(); Console.WriteLine($"\u03C0 = {pi}");
with:
for (int i = 0; i < 3; i++) { try { double pi = server.ComputePi(); Console.WriteLine($"\u03C0 = {pi}"); } catch (Exception e) { Console.WriteLine(e.GetType() + " " + e.Message); } }
-
-
Compile, COM register, and run
ManagedClient
as described inREADME.md
. -
(Unregister when done.)
Expected behavior
AppDomain.CurrentDomain.UnhandledException
is not raised.
Actual behavior
AppDomain.CurrentDomain.UnhandledException
is raised, but only on the first exception.
Regression?
Yes. Works as expected with .NET 8, and works when setting the environment variable DOTNET_LegacyExceptionHandling
to 1
.
Known Workarounds
It currently seems to me that the call to UnhandledException
has no side effects.
Therefore, I'm not sure if it actually might be a workaround to ignore such exceptions in handlers of UnhandledException
, e.g. by somehow marking them.
Configuration
Windows 10 22H2.
.NET SDKs:
- 9.0.200
- 10.0.100-preview.1.25120.13
Other information
-
Same behavior with .NET 9 and .NET 10 preview.
-
I see the same behavior when using VB script, e.g.:
' Run with cscript set server = GetObject("new:{AF080472-F173-4D9D-8BE7-435776617347}") on error resume next Dim i For i = 1 To 3 Dim result result = server.ComputePi() If Err.Number <> 0 Then WScript.Echo "Error: " & Err.Description Err.Clear Else WScript.Echo "result: " & result End If Next
-
When using PowerShell, both the Windows PowerShell and pwsh, I see the same behavior with other projects, however, with this example project, creating a COM object gives me the error
Type library is not registered. (0x80131165)
, but I think this is a different topic. -
I do not see this behavior with the
NativeClient
of this example project, and not with native clients using#import
, and not with the unmodifiedManagedClient
of this example project.