none
Best practice(s) and/or pattern(s) of SocketAsyncEventArgs usage RRS feed

  • General discussion

  • Hello,

    I am wrapping my feeble little brain around the pattern(s) (are they several?) of usage of the SocketAsyncEventArgs. I've read several online blogs and forums, and they all seem to walk away with the same general sort confusion, "what is the best practice?" or "pattern(s) of usage"? I'm afraid that I've got the same sort of confusion.

    On the one hand, I like that the "work horse", if you will, of performing Socket requests has been loosely coupled from the Socket Async methods.

    On the other hand, and I could be wrong, it seems to me as though it is trying to be Async by halves. By this I mean, what's the point of promising an asynchronous operation that ends up "completing synchronously" anyway, and needing to test for the return value, much less inconsistently raising the Completed event when the operation was completed asynchronously?

    For instance, from the Socket.AsyncAccept method documentation, we have the scenario outlined:

    Returns true if the I/O operation is pending. The SocketAsyncEventArgs.Completed event on the e parameter will be raised upon completion of the operation.
    Returns false if the I/O operation completed synchronously. The SocketAsyncEventArgs.Completed event on the e parameter will not be raised and the e object passed as a parameter may be examined immediately after the method call returns to retrieve the result of the operation.

    Given this assumption, it seems like a fairly common wrapper for any given operation would be something like this, presumably which would be contained in the body of a (potentially long-running) Task some place (however, I dare not presume upon anything here...):

    Socket s;
    
    //...
    
    const bool completedSynchronously = false;
    
    //TODO: is the overhead of an event really necessary? for a general, reusable use case, probably so...
    var @event = new ManualResetEvent(false);
    
    //TODO: either created in-situ, or made available as a parameter, argument, reused from a pool, etc
    var args = new SocketAsyncEventArgs();
    
    //TODO: do something else? and/or pass in other handlers to the completed event...
    //but since this is not called when synchronous, must manage that eventuality apart from the Completed event...
    args.Completed += (sender, e) =>
    {
        @event.Set();
    };
    
    //TODO: TBD: could potentially stack event handlers? were it not for inconsistent calling convention...
    //args.Completed += otherEventHandler
    
    //Test for synchronous completion, and set the event
    if (completedSynchronously == s.DoSomethingAsync(args))
    {
        //TODO: TBD: presumably called with Socket for sender, and the args...
        //otherEventHandler(s, args);
        @event.Set();
    }
    
    //TODO: and/or timeout, monitor for CancellationToken, etc
    @event.WaitOne();
    Possibly could combine the base API with something like Reactive Extensions, observable pattern, for best usage, I'm not sure. At minimum, it seems like a fairly common thing to want to do is wrap this asynchronous transactional pattern in a supporting class.

    Am I wrong? Some insights would be helpful, working examples, etc, besides the ones I've worked on personally. At least confirming, denying, or otherwise establishing a best practice.

    Thank you...


    • Changed type mwpowellhtx Monday, April 27, 2015 10:23 PM Not certain that there is a pat answer but rather am interested in broad discussion on the subject
    Monday, April 27, 2015 5:51 PM

All replies