0 people like it.

F#-friendly SocketAsyncEventArgs

The name is a bit trying, but the overall callback approach greatly simplifies the mechanism for calling and handling the System.Net.Sockets.Socket Async methods.

An F#-friendly SocketAsyncEventArgs subclass

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
type AsyncSocketEventArgs(callback: SocketAsyncEventArgs -> unit) as x =
    inherit SocketAsyncEventArgs()
    let mutable disposed = false
    let subscription = x.Completed.Subscribe(callback)
    let dispose disposing =
        if not disposed then
            if disposing then
                subscription.Dispose()
            disposed <- true
    member x.CallbackSync() = callback x
    override x.Finalize() =
        dispose false
    interface IDisposable with
        member x.Dispose() =
            dispose true
            GC.SuppressFinalize(x)

Socket extensions using the AsyncSocketEventArgs type

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
/// Helper method to make Async calls easier.  InvokeAsyncMethod ensures the callback always
/// gets called even if an error occurs or the Async method completes synchronously.
let inline invokeAsyncMethod(asyncmethod, args:AsyncSocketEventArgs) =
    let result = asyncmethod args
    if result <> true then
        args.CallbackSync()

type Socket with 
    member s.AcceptAsync(args) =
        invokeAsyncMethod(s.AcceptAsync, args) 
    member s.ReceiveAsync(args) =
        invokeAsyncMethod(s.ReceiveAsync, args) 
    member s.SendAsync(args) =
        invokeAsyncMethod(s.SendAsync, args) 
    member s.ConnectAsync(args) =
        invokeAsyncMethod(s.ConnectAsync, args)
    member s.DisconnectAsync(args) =
        invokeAsyncMethod(s.DisconnectAsync, args)
Multiple items
type AsyncSocketEventArgs =
  inherit SocketAsyncEventArgs
  interface IDisposable
  new : callback:(SocketAsyncEventArgs -> unit) -> AsyncSocketEventArgs
  member CallbackSync : unit -> unit
  override Finalize : unit -> unit

Full name: Script.AsyncSocketEventArgs


 An F#-friendly SocketAsyncEventArgs subclass.


--------------------
new : callback:(SocketAsyncEventArgs -> unit) -> AsyncSocketEventArgs
val callback : (SocketAsyncEventArgs -> unit)
Multiple items
type SocketAsyncEventArgs =
  inherit EventArgs
  new : unit -> SocketAsyncEventArgs
  member AcceptSocket : Socket with get, set
  member Buffer : byte[]
  member BufferList : IList<ArraySegment<byte>> with get, set
  member BytesTransferred : int
  member ConnectByNameError : Exception
  member ConnectSocket : Socket
  member Count : int
  member DisconnectReuseSocket : bool with get, set
  member Dispose : unit -> unit
  ...

Full name: System.Net.Sockets.SocketAsyncEventArgs

--------------------
SocketAsyncEventArgs() : unit
type unit = Unit

Full name: Microsoft.FSharp.Core.unit
val x : AsyncSocketEventArgs
val mutable disposed : bool
val subscription : IDisposable
event SocketAsyncEventArgs.Completed: IEvent<EventHandler<SocketAsyncEventArgs>,SocketAsyncEventArgs>
member IObservable.Subscribe : callback:('T -> unit) -> IDisposable
IObservable.Subscribe(observer: IObserver<SocketAsyncEventArgs>) : IDisposable
val dispose : (bool -> unit)
val disposing : bool
val not : value:bool -> bool

Full name: Microsoft.FSharp.Core.Operators.not
IDisposable.Dispose() : unit
member AsyncSocketEventArgs.CallbackSync : unit -> unit

Full name: Script.AsyncSocketEventArgs.CallbackSync
override AsyncSocketEventArgs.Finalize : unit -> unit

Full name: Script.AsyncSocketEventArgs.Finalize
type IDisposable =
  member Dispose : unit -> unit

Full name: System.IDisposable
override AsyncSocketEventArgs.Dispose : unit -> unit

Full name: Script.AsyncSocketEventArgs.Dispose
type GC =
  static member AddMemoryPressure : bytesAllocated:int64 -> unit
  static member CancelFullGCNotification : unit -> unit
  static member Collect : unit -> unit + 2 overloads
  static member CollectionCount : generation:int -> int
  static member GetGeneration : obj:obj -> int + 1 overload
  static member GetTotalMemory : forceFullCollection:bool -> int64
  static member KeepAlive : obj:obj -> unit
  static member MaxGeneration : int
  static member ReRegisterForFinalize : obj:obj -> unit
  static member RegisterForFullGCNotification : maxGenerationThreshold:int * largeObjectHeapThreshold:int -> unit
  ...

Full name: System.GC
GC.SuppressFinalize(obj: obj) : unit
val invokeAsyncMethod : asyncmethod:(AsyncSocketEventArgs -> bool) * args:AsyncSocketEventArgs -> unit

Full name: Script.invokeAsyncMethod


 Helper method to make Async calls easier. InvokeAsyncMethod ensures the callback always
 gets called even if an error occurs or the Async method completes synchronously.
val asyncmethod : (AsyncSocketEventArgs -> bool)
val args : AsyncSocketEventArgs
val result : bool
member AsyncSocketEventArgs.CallbackSync : unit -> unit
Multiple items
type Socket =
  new : socketInformation:SocketInformation -> Socket + 1 overload
  member Accept : unit -> Socket
  member AcceptAsync : e:SocketAsyncEventArgs -> bool
  member AddressFamily : AddressFamily
  member Available : int
  member BeginAccept : callback:AsyncCallback * state:obj -> IAsyncResult + 2 overloads
  member BeginConnect : remoteEP:EndPoint * callback:AsyncCallback * state:obj -> IAsyncResult + 3 overloads
  member BeginDisconnect : reuseSocket:bool * callback:AsyncCallback * state:obj -> IAsyncResult
  member BeginReceive : buffers:IList<ArraySegment<byte>> * socketFlags:SocketFlags * callback:AsyncCallback * state:obj -> IAsyncResult + 3 overloads
  member BeginReceiveFrom : buffer:byte[] * offset:int * size:int * socketFlags:SocketFlags * remoteEP:EndPoint * callback:AsyncCallback * state:obj -> IAsyncResult
  ...

Full name: System.Net.Sockets.Socket

--------------------
Socket(socketInformation: SocketInformation) : unit
Socket(addressFamily: AddressFamily, socketType: SocketType, protocolType: ProtocolType) : unit
val s : Socket
member Socket.AcceptAsync : args:AsyncSocketEventArgs -> unit

Full name: Script.AcceptAsync
member Socket.AcceptAsync : args:AsyncSocketEventArgs -> unit
Socket.AcceptAsync(e: SocketAsyncEventArgs) : bool
member Socket.ReceiveAsync : args:AsyncSocketEventArgs -> unit

Full name: Script.ReceiveAsync
member Socket.ReceiveAsync : args:AsyncSocketEventArgs -> unit
Socket.ReceiveAsync(e: SocketAsyncEventArgs) : bool
member Socket.SendAsync : args:AsyncSocketEventArgs -> unit

Full name: Script.SendAsync
member Socket.SendAsync : args:AsyncSocketEventArgs -> unit
Socket.SendAsync(e: SocketAsyncEventArgs) : bool
member Socket.ConnectAsync : args:AsyncSocketEventArgs -> unit

Full name: Script.ConnectAsync
member Socket.ConnectAsync : args:AsyncSocketEventArgs -> unit
Socket.ConnectAsync(e: SocketAsyncEventArgs) : bool
member Socket.DisconnectAsync : args:AsyncSocketEventArgs -> unit

Full name: Script.DisconnectAsync
member Socket.DisconnectAsync : args:AsyncSocketEventArgs -> unit
Socket.DisconnectAsync(e: SocketAsyncEventArgs) : bool
Next Version Raw view Test code New version

More information

Link:http://fssnip.net/8L
Posted:12 years ago
Author:Ryan Riley
Tags: network , sockets , fracture , async , socketasynceventargs