Udostępnij za pośrednictwem


Asynchroniczne przepływy pracy (F#)

W tym temacie opisano obsługę w F# do wykonywania obliczeń asynchronicznie, to znaczy bez blokowania wykonanie innych prac.Na przykład obliczenia asynchronicznego można pisać aplikacje, które mają opanować, które nadal dopasowywać do użytkowników, jak aplikacja wykonuje inną pracę.

async { expression }

Uwagi

W składni poprzednich obliczeń reprezentowane przez expression jest skonfigurowany do uruchamiane asynchronicznie, to znaczy bez blokowania bieżącego wątku obliczeń, gdy wykonywane są operacje asynchronicznego trybu uśpienia, we/wy i innych operacji asynchronicznych.Obliczenia asynchronicznego często są uruchamiane na wątek w tle, podczas gdy wykonywanie jest kontynuowane w bieżącym wątku.Typ wyrażenia jest Async<'a>, gdzie 'a jest to typ zwracany przez wyrażenie podczas return użyć słowa kluczowego.Kod w wyrażeniu jest zwane jest także asynchronicznego blok, lub bloku transmisji asynchronicznej.

Istnieją różne sposoby programowania asynchronicznie oraz Async klasy zawiera metody, które obsługują kilka scenariuszy.Ogólne podejście jest utworzenie Async obiektów, które reprezentują obliczenia lub obliczenia, które mają być uruchamiane asynchronicznie, a następnie uruchom te obliczenia przy użyciu jednej z funkcji wyzwalającego.Różne funkcje wyzwalającego zapewniają różne sposoby uruchamiania asynchronicznego obliczenia i którego jedną użyć zależy czy chcesz użyć bieżącego wątku, wątek w tle lub.NET Framework obiektu zadania, a także, czy dostępne są funkcje kontynuacji, które powinny być uruchamiane po zakończeniu obliczeń.Na przykład, aby uruchomić asynchronicznego obliczeń w bieżącym wątku, można użyć Async.StartImmediate.Po uruchomieniu obliczeń asynchronicznego wątku interfejsu użytkownika nie należy blokować pętli głównych zdarzenia, która przetwarza akcje użytkownika, takich jak naciśnięcia klawiszy i aktywność myszy, aby aplikacja nadal odpowiadać.

Wiązania asynchronicznego przy użyciu let!

W asynchronicznej przepływu pracy niektóre wyrażenia i operacje są synchroniczne i niektóre są dłuższe obliczenia, które są przeznaczone do zwracania wyniku asynchronicznie.Gdy wywołujemy metodę asynchronicznie, zamiast zwykłych let wiążące, użyj let!.Efekt let! jest umożliwienie realizacji kontynuować w innych obliczeniach lub wątki, jak jest w trakcie wykonywania obliczeń.Po prawej stronie let! zwraca wiązania reszty asynchronicznego przepływu pracy wznawia wykonywanie.

Poniższy kod ilustruje różnicę między let i let!.Linia kodu, która korzysta z let po prostu tworzy asynchronicznego obliczeń, jako obiekt, który można uruchomić później przy użyciu, na przykład, Async.StartImmediate lub Async.RunSynchronously.Linia kodu, która korzysta z let! uruchamia obliczeń, a następnie wątek jest zawieszone, dopóki wynik nie będzie dostępny, na których wykonanie punktu w dalszym ciągu.

// let just stores the result as an asynchronous operation.
let (result1 : Async<byte[]>) = stream.AsyncRead(bufferSize)
// let! completes the asynchronous operation and returns the data.
let! (result2 : byte[])  = stream.AsyncRead(bufferSize)

Oprócz let!, można użyć use! do wykonywania wiązania asynchronicznego.Różnica między let! i use! jest taka sama jak różnica między let i use.Dla use!, obiekt jest usuwany z końcem bieżącego zakresu.Należy zauważyć, że w bieżącej wersji języka F#, use! nie zezwala na wartości zainicjowana wartość NULL, mimo że use jest.

Asynchroniczne pierwotnych

Wywoływana jest metoda, która wykonuje pojedynczego zadania asynchroniczne i zwraca wynik asynchronicznego pierwotny, a te są zaprojektowane specjalnie do użytku z let!.Kilka asynchronicznych obiektów pierwotnych są zdefiniowane w bibliotece core F#.Dwie metody takie aplikacje sieci Web są zdefiniowane w module Microsoft.FSharp.Control.WebExtensions: WebRequest.AsyncGetResponse i WebClient.AsyncDownloadString.Zarówno proste kształty pobrać dane ze strony sieci Web, biorąc pod uwagę adresu URL.AsyncGetResponsewytwarza WebResponse obiektu, i AsyncDownloadString daje ciąg, który reprezentuje HTML dla strony sieci Web.

Kilka obiektów pierwotnych asynchronicznych operacji wejścia/wyjścia są uwzględniane w Microsoft.FSharp.Control.CommonExtensions modułu.Metody te rozszerzenia z Stream klasy są Stream.AsyncRead i Stream.AsyncWrite.

W PowerPack F# dostępne są dodatkowe asynchronicznych obiektów pierwotnych.Można również napisać własne asynchronicznych obiektów pierwotnych, definiując funkcji, których pełną treść jest ujęty w bloku transmisji asynchronicznej.

Aby użyć metody asynchronicznej w.NET Framework, które są przeznaczone dla innych modeli asynchronicznego z F# asynchronicznego modelu programowania, utworzyć funkcję zwracającą wartość F# Async obiektu.Biblioteka F# ma funkcje, które ułatwiają to zrobić.

Przykładem przy użyciu Asynchroniczne przepływy pracy jest uwzględnione w tym miejscu; istnieje wiele innych w dokumentacji dla metod Async klasy.

Przykład

W tym przykładzie przedstawiono sposób używania Asynchroniczne przepływy pracy do wykonywania obliczeń równolegle.

W poniższym przykładzie kodu funkcji fetchAsync pobiera tekst HTML jest zwracane z żądania sieci Web.fetchAsync Funkcja zawiera asynchronicznego bloku kodu.Gdy powiązanie jest dokonywane do wyniku asynchronicznego pierwotny, w tym przypadku AsyncDownloadString, let! jest używana zamiast let.

W przypadku użycia funkcji Async.RunSynchronously wykonać operację asynchroniczną i czekać na jej wynik.Na przykład można wykonywać wiele operacji asynchronicznych równolegle, za pomocą Async.Parallel działać wraz z Async.RunSynchronously funkcji.Async.Parallel Funkcja przyjmuje wykaz Async obiektów, kod ustawia dla każdego Async obiektu zadanie do uruchomienia w równolegle i zwraca Async obiekt, który reprezentuje obliczeń równoległych.Tylko dla jednej operacji, call Async.RunSynchronously do rozpoczęcia realizacji.

runAll Funkcja uruchamia trzy Asynchroniczne przepływy pracy równolegle i czeka, aż wszystkie zakończyły.

open System.Net
open Microsoft.FSharp.Control.WebExtensions

let urlList = [ "Microsoft.com", "https://www.microsoft.com/" 
                "MSDN", "https://msdn.microsoft.com/" 
                "Bing", "https://www.bing.com"
              ]

let fetchAsync(name, url:string) =
    async { 
        try 
            let uri = new System.Uri(url)
            let webClient = new WebClient()
            let! html = webClient.AsyncDownloadString(uri)
            printfn "Read %d characters for %s" html.Length name
        with
            | ex -> printfn "%s" (ex.Message);
    }

let runAll() =
    urlList
    |> Seq.map fetchAsync
    |> Async.Parallel 
    |> Async.RunSynchronously
    |> ignore

runAll()

Zobacz też

Informacje

Control.Async — Klasa (F#)

Inne zasoby

Materiały referencyjne dotyczące języka F#

Wyrażenia obliczeń (F#)