Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

8.0 Discussion about public events #973

Open
Assignees
lukebakken
Milestone
@bollhals

Description

@bollhals

Originating from#970 the discussion is about how we deal with the currently public events.

Starter was the post from@stebet

I'm wondering if a better implementation than having the events is to have a "handler" interface that can be registered in the channels, so instead of events likeFlowControlChanged etc. there would be an interface called IChannelHandler, that could be registered like consumers. These handlers would exposes the standard methods:

publicinterfaceIChannelHandler{ValueTaskOnFlowControl(IChannelchannel,boolactive);ValueTaskOnPublicAckReceived(IChannelchannel);  ...}

That way it's easy to override whatever logic to take care of in a class (logging, waiting for publish confirms etc.) and then register it with the channel interfacechannel.RegisterHandler(myCustomHandler);.

The channel can maintain those handlers in a list and execute them (in parallel if needed) as events happen. That way those implementing the handlers can also do things asynchronously with minimal effort and the channel code would be free of all the async event workarounds we currently have. Logging and all sorts of instrumentation or special logic can then be added to augment the channel interface, especially if the handlers can have a reference to the Channel objects themselves and access other things.

I've done some measurements today regarding performance of various ways of invoking actions To have also an idea about what this means.

MethodactionMeanErrorStdDevRatioRatioSDGen 0Gen 1Gen 2Allocated
GetInvocationListSyste(...)nt32] [29]14.7064 ns1.0487 ns0.0575 ns1.000.000.0068--32 B
GetInvocationListSyste(...)nt32] [29]31.4116 ns12.2659 ns0.6723 ns2.140.050.0085--40 B
DirectSyste(...)nt32] [29]0.6689 ns0.1508 ns0.0083 ns0.050.00----
DirectSyste(...)nt32] [29]7.2192 ns0.2554 ns0.0140 ns0.490.00----
Reflection.EmitSyste(...)nt32] [29]14.8313 ns0.2667 ns0.0146 ns1.010.00----
Reflection.EmitSyste(...)nt32] [29]25.1454 ns0.8545 ns0.0468 ns1.710.01----
InterfaceSyste(...)Test] [66]6.7287 ns0.8310 ns0.0455 ns??----
InterfaceSyste(...)Test] [66]11.7185 ns1.1444 ns0.0627 ns??----
List_ActionSyste(...)t32]] [64]6.7017 ns0.1550 ns0.0085 ns??----
List_ActionSyste(...)t32]] [64]11.5592 ns0.1531 ns0.0084 ns??----

Where

  • GetInvocationList is the "current way" of getting the individual delegates
  • Direct is just calling delegate.Invoke() (no individual control over invocation)
  • Reflection.Emit is retrieving the _invocationList field of a delegate via Reflection.Emit (+- what is returned by GetInvocationList)
  • Interface is a single method interface stored in a list
  • List_Action is all induvidual delegates stored within a list and iterated over

And the first entry always being for one attached event handler and the 2nd one for two handlers (action += handler) (Or entries in the list)

I think the relevant notes are:

  • GetInvocationList is kind of slow and allocates
  • Direct is obviously unbeatable, but won't allow us to do what we want
  • Emit is nice, a but not fast enough while also having additional dependency
  • Interface / List_Action are reasonably fast while not allocating. (Downside though is the increased complexity to store them in the list + the allocation will take place there)

This issue should be taken as the place to dicuss where we want to move to with the events in our public API.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions


    [8]ページ先頭

    ©2009-2025 Movatter.jp