Async.FromBeginEnd<'T> 方法 (F#)
更新:2010 年 7 月
在 CLI API 內使用的樣式中,建立關於 Begin/End 動作組的非同步計算。
命名空間/模組路徑: Microsoft.FSharp.Control
組件:FSharp.Core (在 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)
參數
beginAction
型別:AsyncCallback * obj -> IAsyncResult會起始傳統 CLI 非同步作業的函式。
endAction
型別:IAsyncResult -> 'T會完成傳統 CLI 非同步作業的函式。
cancelAction
型別:(unit -> unit)取消作業的要求提出後要執行的選擇性函式。
傳回值
用於包裝指定之 Begin/End 函式的非同步計算。
備註
就例如下列程式碼會建立包裝 Web 服務呼叫的非同步計算。
Async.FromBeginEnd(ws.BeginGetWeather,ws.EndGetWeather)
當計算執行時, beginFunc執行的回呼,用來表示註解的接續的 計算。 叫用回呼時,會使用 endFunc 擷取整體結果。
計算會在等待作業完成期間回應取消。 如果發生取消而且已指定 cancelAction,便會執行取消作業,而且計算作業會繼續等待作業完成。 如果 cancelAction未指定,取消通知會造成立即,停止計算,而且後續的引動過程的回呼會被忽略
範例
下列程式碼範例會示範如何建立一個 F # 非同步計算從使用開始/結束模式的.NET 非同步 API。 此範例使用.NET 通訊端 API, System.Net.Sockets 它會實作簡單的伺服器應用程式接受連線,從一個的伺服器接收資料,然後傳送回應。
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)
下列程式碼範例會顯示與伺服器程式碼,在先前的範例中可以使用用戶端程式碼。
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()
範例輸出
平台
Windows 7、Windows Vista SP2、Windows XP SP3、Windows XP x64 SP2、Windows Server 2008 R2、Windows Server 2008 SP2、Windows Server 2003 SP2
版本資訊
F# 執行階段
支援版本:2.0、4.0
Silverlight
支援版本:3
請參閱
參考
Microsoft.FSharp.Control 命名空間 (F#)
變更記錄
日期 |
History |
原因 |
---|---|---|
2010 年 7 月 |
加入程式碼範例。 |
資訊加強。 |