Why does every single dynamic call raise two exceptions, and can they be suppressed?

Consider the following:

using System; using System.Dynamic; using System.Linq; namespace DynamicObjectTest { class Program { static void Main(string[] args) { dynamic dyn = new TestDynamic(); Console.ReadKey(); foreach (var i in Enumerable.Range(0, 100)) { Console.WriteLine(dyn.Foo()); Console.WriteLine(dyn.Bar()); } Console.ReadKey(); } } class TestDynamic : DynamicObject { public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) { if (binder.Name == "Foo") { result = "Bar"; return true; } else if (binder.Name == "Bar") { result = "Foo"; return true; } return base.TryInvokeMember(binder, args, out result); } } } 

When this program starts, four exceptions of the RuntimeBinderException type are RuntimeBinderException . You can observe this either by hacking all excepted exceptions (Debugging / Exceptions ... / check the box next to “Exclude Common Language Rutime exceptions”) or using perfmon:

enter image description here

Now these exceptions are obviously caught and handled internally, because after that the TryInvokeMember method TryInvokeMember called. However, it seems cruel and misuse of exceptions if you subscribe to the mantra “use exceptions only in exceptional circumstances”. For my specific example, this is not a problem, because the same element is repeatedly called - Foo and Bar . However, I have other scenarios in which members are much less static.

Is there anything that can be done to help runtime call TryInvokeMember without any exceptions?

+6
source share
1 answer

The system sometimes throws and catches exceptions inside. You can’t do anything (except sending feedback http://connect.microsoft.com/VisualStudio , but there is no reason, as this is unlikely to affect performance - other service-related data before DynamicObject significantly exceeds this).

(If I had to guess, internally, it could be like a hardware "page error" exception in memory: the system allows an exception to occur, then catches it and combines it so that future execution succeeds. It is extremely efficient because it uses processor exception functions, so that conditional branching is not required in the code.)

NOTE. To try the code in the original message, be sure to disable the "Only my code" option, as well as configure it to break all abandoned exceptions.

+2
source

Source: https://habr.com/ru/post/901609/


All Articles