-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add the IAction***, IFunc*** abstractions and make C# automatically inherit them by delegates #3336
Comments
This is not a language feature request as it would be the BCL's responsibility to add the interfaces and the runtime's responsibility to have delegate "automatically" implement them. I can't see this happening, though, as this would require that the BCL add thousands of interface types to account for all of the different permutations of arity and directionality that are possible. |
@HaloFour thank you for the tip to move this proposal to the runtime.
So if we will support this only for Nmax=8 it will be not so expensive. We already have proposals to bring such permutations for already existing Action, Func For example in this proposal. |
28k types would add an enormous amount of bloat to the runtime. The number of types loaded into a basic .NET Core 3.x console app today is less than 10% of that. Foisting that requirement on all .NET processes doesn't sound remotely reasonable. |
Adding 28k additional types would almost certainly be a runtime breaking change for at least one of the supported target runtimes. For a prior example of exactly this, see 65535 interfaces ought to be enough for anybody. Also ... the overhead in moving work to another thread is significant. The exact amount depends on your processor architecture, memory architecture, operating system, current CPU load, and so on. If memory serves, "typical" would be in the range 100 microseconds to 50 milliseconds. A clock cycle or four to bounce execution through a nested delegate is probably so minor a different that you wouldn't be able to detect the difference for the statistical noise. |
Also interface calls are slower than delegates, so I'm not even sure this would be a performance win. |
We don't need interfaces, we need implicit conversion between delegates with same signature. Also |
@dmitriyse This is the pattern I've been using (usually a private static method rather than a lambda just to keep stack traces nice): public void RunOnMyThread(Action<object> action, object obj)
{
ThreadPool.QueueUserWorkItem(
state =>
{
var (action, obj) = ((Action<object>, object))state!;
action(obj);
},
state: (action, obj));
} A lot of BCL code uses this technique but with Tuple instead of ValueTuple. |
Oh, look at this! .NET Core has a generic overload that allows you to even skip allocating for ThreadPool.QueueUserWorkItem(
state => state.action(state.obj),
state: (action, obj),
preferLocal: true/false); |
@theunrepentantgeek, @HaloFour thank you for the tip, that ~28K is an unacceptable increase of types count for the current runtime. I have updated the topic. I know about For other library writers with a performance-critical part is also beneficial to have some "100% free" delegate conversion. This proposal is NOT about improvements in BCL library code like Yes this proposal is a duplicate of dotnet/runtime#4331 Even if C# and runtime will allow to convert Action to WaitCallback silently, object myUnknown = .... <- Action<Object>;
if (myUnknown is WaitCallback tst) // Ok we hacked runtime to make "is operator" know about signature equivalence
{
}
if (myUnknown.Type.Name == "WaitCallback") // This code will be broken
{
// Bad written code
} |
Alternatives:
|
Found a better approach, see dotnet/runtime#4331 (comment) |
Instantiated delegates are not interchangeable even if they have compatible signatures.
In performance-critical methods this causes small performance leaks:
To avoid this, C# languages and the Base Class Library could be improved (
Action
andFunc
delegates):Additional benefits of the proposed feature:
The text was updated successfully, but these errors were encountered: