Zaman uyumsuz ifadeler

Bu makalede, zaman uyumsuz ifadeler için F # ' da destek açıklanır. Zaman uyumsuz ifadeler hesaplamaları zaman uyumsuz olarak gerçekleştirmenin bir yolunu sağlar, diğer bir deyişle, diğer çalışmanın yürütülmesini engellemeden. Örneğin, zaman uyumsuz hesaplamalar, uygulama diğer işleri gerçekleştirirken kullanıcılara yanıt vermeye devam eden uo uygulamaları yazmak için kullanılabilir.

Zaman uyumsuz kod ayrıca, .NET görevlerini doğrudan oluşturan görev ifadelerikullanılarak da yazılabilir. .NET görevleri oluşturan veya tüketen .NET kitaplıklarıyla kapsamlı olarak birlikte çalışırken görev ifadelerinin kullanılması tercih edilir. F # ' da çoğu zaman uyumsuz kodu yazarken, F # zaman uyumsuz ifadeler tercih edilir çünkü daha fazla kısa, daha fazla kompozisyon ve .NET görevleriyle ilişkili belirli uyarıları önleyin.

Syntax

async { expression }

Açıklamalar

Önceki sözdiziminde tarafından temsil edilen hesaplama zaman uyumsuz expression olarak çalışacak şekilde ayarlanır, yani zaman uyumsuz uyku işlemleri, g/ç ve diğer zaman uyumsuz işlemler gerçekleştirildiğinde geçerli hesaplama iş parçacığını engellemeden yapılır. Zaman uyumsuz hesaplamalar genellikle, yürütme geçerli iş parçacığında devam ederken arka plan iş parçacığında başlatılır. İfadenin türü, Async<'T> , 'T return anahtar sözcüğü kullanıldığında ifade tarafından döndürülen türdür.

AsyncSınıfı, birkaç senaryoyu destekleyen yöntemler sağlar. Genel yaklaşım, Async zaman uyumsuz olarak çalıştırmak istediğiniz hesaplamayı veya hesaplamaları temsil eden nesneler oluşturmak ve ardından tetikleme işlevlerinden birini kullanarak bu hesaplamaları başlatmalıdır. Kullandığınız tetikleyici, geçerli iş parçacığını, arka plan iş parçacığını veya .NET görev nesnesini kullanmak istediğinize bağlıdır. Örneğin, geçerli iş parçacığında zaman uyumsuz bir hesaplama başlatmak için kullanabilirsiniz Async.StartImmediate . UI iş parçacığından zaman uyumsuz bir hesaplamayı başlattığınızda, uygulamanız yanıt vermiyor gibi kullanıcı eylemlerini işleyen ana olay döngüsünü engellemez.

Let kullanarak zaman uyumsuz bağlama!

Zaman uyumsuz ifadede bazı ifadeler ve işlemler zaman uyumludur ve bazıları zaman uyumsuzdur. Sıradan bağlama yerine bir yöntemi zaman uyumsuz olarak çağırdığınızda let kullanırsınız let! . ' Nin etkisi, let! hesaplamanın gerçekleştirildiği için yürütmenin diğer hesaplamalar veya iş parçacıklarında devam etmesine olanak tanır. Bağlamanın sağ tarafı let! döndüğünde, zaman uyumsuz ifadenin geri kalanı yürütmeyi sürdürür.

Aşağıdaki kod ve arasındaki farkı gösterir let let! . Tarafından kullanılan kod satırı, let daha sonra, örneğin veya kullanarak daha sonra çalıştırabileceğiniz bir nesne olarak zaman uyumsuz bir hesaplama oluşturur Async.StartImmediate Async.RunSynchronously . Tarafından kullanılan kod satırı let! hesaplamayı başlatır ve zaman uyumsuz bekleme gerçekleştirir: sonuç kullanılabilir olana kadar iş parçacığı askıya alınır ve bu noktada yürütme devam eder.

// 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)

let! Yalnızca F # zaman uyumsuz hesaplamaları doğrudan beklemek için kullanılabilir Async<T> . Zaman uyumsuz işlemlerin diğer türlerini dolaylı olarak bekleleyebilirsiniz:

  • Task<TResult>İle birleştirerek .net görevleri ve genel olmayan TaskAsync.AwaitTask
  • Ve ile birleştirerek .NET değer görevleri ValueTask<TResult> ve genel olmayan ValueTask .AsTask()``Async.AwaitTask
  • İle birleştirerek F # RFC FS-1097içinde belirtilen "GetAwaiter" deseninin ardından gelen herhangi bir nesne task { return! expr } |> Async.AwaitTask .

Denetim Akışı

Zaman uyumsuz ifadeler,,,,, ve gibi denetim akışı yapıları içerebilir for .. in .. do while .. do try .. with .. try .. finally .. if .. then .. else if .. then .. . Bunlar, zaman with uyumlu olarak yürütülen ve işleyicileri dışında, daha fazla zaman uyumsuz yapıları dahil edebilir finally .

F # zaman uyumsuz ifadeler zaman uyumsuz olarak desteklenmez try .. finally .. . Bu durum için bir görev ifadesi kullanabilirsiniz.

use ve use! bağlamalar

Zaman uyumsuz ifadeler içinde use bağlamalar, türündeki değerlere bağlanabilir IDisposable . İkinci için, elden çıkarma temizleme işlemi zaman uyumsuz olarak yürütülür.

' A ek olarak let! , use! zaman uyumsuz bağlamalar gerçekleştirmek için kullanabilirsiniz. Ve arasındaki fark let! , use! ve arasındaki farklılığı ile aynıdır let use . İçin use! , nesnesi geçerli kapsamın kapandığı sırada atıldı. F # ' ın geçerli sürümünde, use! bir değerin null olarak başlatılmasına, ancak olsa da izin vermediğini unutmayın use .

Zaman uyumsuz temel öğeler

Tek bir zaman uyumsuz görev gerçekleştiren ve sonucu döndüren bir yöntem, zaman uyumsuz temel değer olarak adlandırılır ve bunlar özellikle ile kullanılmak üzere tasarlanmıştır let! . Çeşitli zaman uyumsuz temel türler, F # Çekirdek Kitaplığı 'nda tanımlanmıştır. Web uygulamaları için iki tür yöntemi, modülünde tanımlanmıştır FSharp.Control.WebExtensions : WebRequest.AsyncGetResponse ve WebClient.AsyncDownloadString . Her iki temel bir Web sayfasından veri indirir. AsyncGetResponse bir System.Net.WebResponse nesnesi üretir ve bir AsyncDownloadString Web sayfası için HTML 'i temsil eden bir dize oluşturur.

Zaman uyumsuz g/ç işlemlerine yönelik çeşitli temel türler modüle dahildir FSharp.Control.CommonExtensions . Sınıfının bu genişletme yöntemleri System.IO.Stream Stream.AsyncRead ve ' dir Stream.AsyncWrite .

Gövdesi zaman uyumsuz bir ifade olan bir işlev veya yöntem tanımlayarak kendi zaman uyumsuz temel temellerinizi de yazabilirsiniz.

f # zaman uyumsuz programlama modeliyle diğer zaman uyumsuz modeller için tasarlanan .NET Framework zaman uyumsuz yöntemler kullanmak için, f # nesnesi döndüren bir işlev oluşturursunuz Async . F # kitaplığı, bunu kolayca yapmayı sağlayan işlevlere sahiptir.

Zaman uyumsuz ifadeler kullanmanın bir örneği buraya dahildir; zaman uyumsuz sınıfyöntemlerine ilişkin belgelerde birçok başka tane vardır.

Bu örnek, zaman uyumsuz ifadelerin kodu paralel olarak yürütmek için nasıl kullanılacağını gösterir.

Aşağıdaki kod örneğinde, bir işlev fetchAsync bir Web isteğinden döndürülen HTML metnini alır. fetchAsyncİşlev zaman uyumsuz bir kod bloğu içeriyor. Bu durumda, zaman uyumsuz temel öğenin sonucuna bir bağlama yapıldığında, AsyncDownloadString let! yerine kullanılır let .

İşlevini, Async.RunSynchronously zaman uyumsuz bir işlem yürütmek ve bunun sonucunu beklemek için kullanırsınız. Örnek olarak, işlevini işleviyle birlikte kullanarak birden çok zaman uyumsuz işlemi paralel olarak çalıştırabilirsiniz Async.Parallel Async.RunSynchronously . Async.Parallelİşlevi nesnelerinin bir listesini alır Async , her Async görev nesnesi için paralel olarak çalışacak kodu ayarlar ve Async paralel hesaplamayı temsil eden bir nesne döndürür. Tek bir işlemin olduğu gibi Async.RunSynchronously yürütme işlemini başlatmak için öğesini çağırın.

runAllİşlev, paralel olarak üç zaman uyumsuz ifade başlatır ve hepsini tamamlanana kadar bekler.

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

let urlList = [ "Microsoft.com", "http://www.microsoft.com/"
                "MSDN", "http://msdn.microsoft.com/"
                "Bing", "http://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()

Ayrıca bkz.