Sdílet prostřednictvím


Async.FromBeginEnd<'T> – metoda (F#)

Styl použitý v rozhraní API CLI vytvoří asynchronní výpočtu ve dvojici zahájení a ukončení akce.

Cesta k oboru názvů nebo modul: Microsoft.FSharp.Control

Sestavení: FSharp.Core (v FSharp.Core.dll)

// Signature:
static member FromBeginEnd : (AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * ?(unit -> unit) -> Async<'T>

// Usage:
Async.FromBeginEnd (beginAction, endAction)
Async.FromBeginEnd (beginAction, endAction, cancelAction = cancelAction)

Parametry

  • beginAction
    Type: AsyncCallback * obj -> IAsyncResult

    Funkci inicializace tradiční CLI asynchronní operace.

  • endAction
    Typ:IAsyncResult -> 'T

    Funkce dokončování tradiční CLI asynchronní operace.

  • cancelAction
    Type: (unit -> unit)

    Volitelné funkce vykonávaná při zrušení je požadována.

Vrácená hodnota

Asynchronní výpočtu obtékání dané funkce zahájení a ukončení.

Poznámky

Například následující kód vytvoří asynchronní výpočtu, který se zalamuje volání webové služby.

Async.FromBeginEnd(ws.BeginGetWeather,ws.EndGetWeather)

Při spuštění výpočtu beginFunc je spuštěn s zpětné volání, které představuje pokračování výpočtu.Při zpětném volání, celkový výsledek je získána pomocí endFunc.

Výpočtu bude odpovídat na zrušení při čekání na dokončení operace.Pokud dojde k zrušení, a cancelAction je určen, a poté je proveden a výpočtu nadále čekat na dokončení operace.Pokud cancelAction není zadána, způsobí zrušení výpočtu okamžitě zastavit a následné vyvolání zpětného volání jsou ignorovány.

Příklad

Následující příklad kódu ukazuje, jak vytvořit F# asynchronní výpočtu z .net asynchronní API, které používá vzorek zahájení a ukončení.V příkladu .net soketu rozhraní API v System.Net.Sockets.Je implementace aplikace jednoduchý server, který přijímá připojení, obdrží data od klienta a odešle odpověď.

module SocketServer =

    open System.Net
    open System.Net.Sockets
    open System.Collections.Generic

    let toIList<'T> (data : 'T array) =
        let segment = new System.ArraySegment<'T>(data)
        let data = new List<System.ArraySegment<'T>>() :> IList<System.ArraySegment<'T>>
        data.Add(segment)
        data

    type Socket with 
        member this.MyAcceptAsync() =
            Async.FromBeginEnd((fun (callback, state) -> this.BeginAccept(callback, state)),
                               this.EndAccept)
        member this.MyConnectAsync(ipAddress : IPAddress, port : int) =
            Async.FromBeginEnd(ipAddress, port,
                               (fun (ipAddress:IPAddress, port, callback, state) ->
                                   this.BeginConnect(ipAddress, port, callback, state)),
                               this.EndConnect)
        member this.MySendAsync(data : byte array, flags : SocketFlags) =
            Async.FromBeginEnd(toIList data, flags, 
                               (fun (data : IList<System.ArraySegment<byte>>,
                                     flags : SocketFlags, callback, state) ->
                                         this.BeginSend(data, flags, callback, state)),
                               this.EndSend)
        member this.MyReceiveAsync(data : byte array, flags : SocketFlags) =
            Async.FromBeginEnd(toIList data, flags, 
                               (fun (data : IList<System.ArraySegment<byte>>,
                                     flags : SocketFlags, callback, state) ->
                                         this.BeginReceive(data, flags, callback, state)),
                               this.EndReceive)

    let port = 11000

    let socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
    let ipHostInfo = Dns.Resolve(Dns.GetHostName())
    let localIPAddress = ipHostInfo.AddressList.[0]
    let localEndPoint = new IPEndPoint(localIPAddress, port)
    socket.Bind(localEndPoint)


    let connectSendReceive (socket : Socket) =
        async {
            do! socket.MyConnectAsync(ipHostInfo.AddressList.[0], 11000)
            let buffer1 = [| 0uy .. 255uy |]
            let buffer2 = Array.zeroCreate<byte> 255
            let flags = new SocketFlags()
            let! flag = socket.MySendAsync(buffer1, flags)
            let! result = socket.MyReceiveAsync(buffer2, flags)
            return buffer2
        }

    let acceptReceiveSend (socket : Socket) =
        async {
            printfn "Listening..."
            socket.Listen(10)
            printfn "Accepting..." 
            let! socket = socket.MyAcceptAsync()

            let buffer1 = Array.zeroCreate<byte> 256
            let flags = new SocketFlags()
            printfn "Receiving..." 
            let! nBytes = socket.MyReceiveAsync(buffer1, flags)
            printfn "Received %d bytes from client computer." nBytes
            let buffer2 = Array.rev buffer1
            printfn "Sending..." 
            let! flag = socket.MySendAsync(buffer2, flags)
            printfn "Completed." 
            return buffer2
        }

    let taskServer = Async.StartAsTask(acceptReceiveSend(socket))    
    taskServer.Wait()
    socket.Close()

Výsledek

  
  
  
  
  
  

Následující příklad kódu ukazuje kód klienta, který lze použít společně s kódem server v předchozím příkladu.

module SocketClient =

    open System.Net
    open System.Net.Sockets
    open System.Collections.Generic

    let toIList<'T> (data : 'T array) =
        let segment = new System.ArraySegment<'T>(data)
        let data = new List<System.ArraySegment<'T>>() :> IList<System.ArraySegment<'T>>
        data.Add(segment)
        data

    type Socket with 
        member this.MyAcceptAsync(receiveSize) =
            Async.FromBeginEnd(receiveSize,
                               (fun (receiveSize, callback, state) ->
                                   this.BeginAccept(receiveSize, callback, state)),
                               this.EndConnect)
        member this.MyConnectAsync(ipAddress : IPAddress, port : int) =
            Async.FromBeginEnd(ipAddress, port,
                               (fun (ipAddress:IPAddress, port, callback, state) ->
                                   this.BeginConnect(ipAddress, port, callback, state)),
                               this.EndConnect)
        member this.MySendAsync(data, flags : SocketFlags) =
            Async.FromBeginEnd(toIList data, flags, 
                               (fun (data : IList<System.ArraySegment<byte>>,
                                     flags : SocketFlags, callback, state) ->
                                         this.BeginSend(data, flags, callback, state)),
                               this.EndSend)
        member this.MyReceiveAsync(data, flags : SocketFlags) =
            Async.FromBeginEnd(toIList data, flags, 
                               (fun (data : IList<System.ArraySegment<byte>>,
                                     flags : SocketFlags, callback, state) ->
                                         this.BeginReceive(data, flags, callback, state)),
                               this.EndReceive)

    let port = 11000

    let socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
    let ipHostEntry = Dns.Resolve("hostname.contoso.com")
    printfn "Server address: %s" (ipHostEntry.AddressList.[0].ToString())

    let connectSendReceive (socket : Socket) =
        async {
            do! socket.MyConnectAsync(ipHostEntry.AddressList.[0], 11000)
            printfn "Connected to remote host." 
            let buffer1 = [| 0uy .. 255uy |]
            let buffer2 = Array.zeroCreate<byte> 255
            let flags = new SocketFlags()
            printfn "Sending data..." 
            let! flag = socket.MySendAsync(buffer1, flags)
            printfn "Receiving data..." 
            let! result = socket.MyReceiveAsync(buffer2, flags)
            printfn "Received data from remote host." 
            return buffer2
        }

    let acceptReceiveSend (socket : Socket) =
        async {
            socket.Listen(1)
            do! socket.MyAcceptAsync(256)
            let buffer1 = Array.zeroCreate<byte> 255
            let flags = new SocketFlags()
            let! flag = socket.MyReceiveAsync(buffer1, flags)
            let buffer2 = Array.rev buffer1
            let! flag = socket.MySendAsync(buffer2, flags)
            return buffer2
        }

    let taskClient = Async.StartAsTask(connectSendReceive(socket))

    taskClient.Wait()
    taskClient.Result |> Array.iter (fun elem -> printf "%d " elem)

Vzorový výstup

  
  
  
  
  

Platformy

Windows 8, Windows 7, Windows Server 2012 Windows Server 2008 R2

Informace o verzi

F# základní verze knihovny

Podporovány: 2.0, 4.0, přenosné

Viz také

Referenční dokumentace

Control.Async – třída (F#)

Microsoft.FSharp.Control – obor názvů (F#)