1

So I have an IOCP project with a SocketAsyncEventArgs pool that makes them re-usable and reduces the heavy allocation task of SocketAsyncEventArgs.

I assume that when the SocketAsyncEventArgs.Completed event gets invoked, staying re-usable(not disposed), the Completed event hooked in chain will not be automatically set to null. Therefore, I have to manually clean up the event, if I do not want the specific event to be fired multiple times.

Is my assumption about SocketAsyncEventArgs.Completed correct? or is it somewhat internally managed?

The code below might explain more clearly:

void Foo(SocketAsyncEventArgs e) // Call-back 
{
     DoJob(e);

     // Should I do it? 
     // e.Completed -= Foo;
}

Thanks in advance.

Dean Seo
  • 5,486
  • 3
  • 30
  • 49
  • 1
    I know nothing about this, but since nobody else has answered or commented: This whole design is prone to timing vulnerabilities. If you do need to remove the event handler from e.Completed to avoid unwanted multiple calls, then you should probably do it _before_ calling DoJob(), not after. But even then there may be timing vulnerabilities. Anyway, is this in the part of .Net which is now open source? If so you can find your answer there. – RenniePet Nov 24 '14 at 07:52
  • Thanks. Probably I should rather consider more stable design where I do not have to worry about such a thing than trying to clear the Completed event. Appreciated. – Dean Seo Nov 24 '14 at 09:54

1 Answers1

2

The correct way to use the SocketAsyncEventArgs class is to add your handler once when you create the instance. Upon completion, you then just return the instance to the pool. You don't need to remove the handler; you just don't add the handler again when you pull a new instance from your pool.

Don't forget that there are other fields — i.e. those related to the specific completion you're processing — which you do want to be cleared. Once you are done with the current operation, you can either clear them before you return the instance to the pool, or you can just wait until you are retrieving the instance from the pool the next time you use it. IMHO it is better to clear the values before you return it to the pool, since for reference type values that will ensure the objects are collectable if they are no longer used elsewhere, instead of having "phantom" references from your pool keeping them reachable.

Peter Duniho
  • 68,759
  • 7
  • 102
  • 136