Udostępnij za pośrednictwem


Mostkowanie z istniejącymi źródłami asynchronicznymi

Oprócz zdarzeń platformy .NET w .NET Framework istnieją inne asynchroniczne źródła danych. Jednym z nich jest wzorzec metody asynchronicznej. W tym wzorcu projektowym udostępniane są dwie metody. Jedna metoda (zwykle o nazwie BeginX) służy do uruchamiania obliczeń i zwraca dojście IAsyncResult przekazane do drugiej metody (zwykle o nazwie EndX), która następnie pobiera wynik obliczeń. Ukończenie jest zwykle sygnalizowane przez zaimplementowanie delegata AsyncCallback lub sondowanie elementu IAsyncResult.IsCompleted. Kod jest często trudny do odczytania i konserwacji. W tym temacie pokażemy, jak używać metod fabryki Rx do konwertowania takich jakynchroniczne źródła danych do obserwowanych sekwencji.

Konwertowanie wzorców asynchronicznych na obserwowane sekwencje

Wiele metod asynchronicznych na platformie .NET jest zapisywanych przy użyciu podpisów, takich jak BeginX i EndX, gdzie X to nazwa metody wykonywana asynchronicznie. BeginX przyjmuje argumenty do wykonania metody , AsyncCallback, która jest akcją, która podejmuje element IAsyncResult i nie zwraca niczego, a na koniec stan obiektu. Funkcja EndX pobiera element IAsyncResult, który jest przekazywany z elementu AsyncCallback, aby pobrać wartość wywołania asynchronicznego.

Operator FromAsyncPattern typu Obserwowalnego opakowuje metody Begin i End (które są przekazywane jako parametry do operatora) i zwraca funkcję, która przyjmuje te same parametry co Begin i zwraca zauważalne. To możliwe do obserwowania reprezentuje sekwencję publikującą pojedynczą wartość, która jest asynchronicznym wynikiem właśnie określonego wywołania.

W poniższym przykładzie przekonwertujemy elementy BeginRead i EndRead dla obiektu stream , który używa wzorca IAsyncResult do funkcji zwracającej obserwowaną sekwencję. Dla parametrów ogólnych operatora FromAsyncPattern określamy typy argumentów BeginRead do wywołania zwrotnego. Ponieważ metoda EndRead zwraca wartość, dołączamy ten typ jako końcowy parametr ogólny dla metody FromAsyncPattern. Jeśli umieścisz wskaźnik myszy na elemecie var , zauważysz, że wartość zwracana przez funkcję FromAsyncPattern jest delegatem funkcji, który ma następujący podpis: Func<byte[], int32,int32, IObservable<int32>>, co oznacza, że ta funkcja przyjmuje 3 parametry (te same dla elementu BeginRead) i zwraca element IObservable<Int32>.read Ta wartość IObservable zawiera jedną wartość, która jest liczbą całkowitą zwracaną przez element EndRead i zawiera liczbę bajtów odczytanych ze strumienia z zakresu od zera (0) do liczby żądanych bajtów. Ponieważ teraz otrzymujemy element IObservable zamiast elementu IAsyncResult, możemy użyć wszystkich operatorów LINQ dostępnych do obserwowania i subskrybowania, analizowania lub redagowania.

Stream inputStream = Console.OpenStandardInput();
var read = Observable.FromAsyncPattern<byte[], int, int, int>(inputStream.BeginRead, inputStream.EndRead);
byte[] someBytes = new byte[10];
IObservable<int> source = read(someBytes, 0, 10);
IDisposable subscription = source.Subscribe(
                            x => Console.WriteLine("OnNext: {0}", x),
                            ex => Console.WriteLine("OnError: {0}", ex.Message),
                            () => Console.WriteLine("OnCompleted"));
Console.ReadKey();