Udostępnij za pośrednictwem


Instruktaż: Dostęp do sieci Web za pomocą transmisji asynchronicznej i poczekać (C# i Visual Basic)

Można pisać programy asynchronicznego łatwiej i intuicyjnie przy użyciu funkcji, które wprowadzane są w Visual Studio 2012.Możesz napisać asynchronicznego kodu, który wygląda jak synchroniczne kodu i że to kompilator obsługiwać funkcje zwrotne trudne i kontynuacji, które asynchronicznego kodu zwykle pociąga za sobą.

Aby uzyskać więcej informacji na temat funkcji komunikacji asynchronicznej, zobacz Asynchroniczne programowania przy użyciu asynchronicznej i poczekać (C# i Visual Basic).

W tym instruktażu zaczyna się od synchroniczne aplikacji Windows Presentation Foundation (WPF), która sumuje liczbę bajtów w sieci Web.Instruktaż następnie konwertuje aplikacji do asynchronicznego roztworu przy użyciu nowych funkcji.

Jeśli nie chcesz samemu budować aplikacje, można pobrać "próbki asynchroniczne: dostęp do Przewodnik po składnikach Web (C# i Visual Basic)" z Przykładów kodu autora.

W tym instruktażu możesz wykonać następujące zadania:

  • Create a WPF application.

  • Design a simple WPF MainWindow window.

  • Add a reference.

  • Add Imports statements or using directives.

  • Create a synchronous solution.

  • Test the synchronous solution.

  • Convert GetURLContents to an asynchronous method.

  • Convert SumPageSizes to an asynchronous method.

  • Convert startButton_Click to an asynchronous method.

  • Test the asynchronous solution.

  • Replace GetURLContentsAsync with a .NET Framework method.

  • Complete Code Examples from the Walkthrough

Wymagania wstępne

Visual Studio 2012musi być zainstalowany na komputerze.Aby uzyskać więcej informacji, zobacz sieci Web firmy Microsoft.

Aby utworzyć aplikację programu WPF

  1. Uruchom program Visual Studio.

  2. Na pasku menu wybierz Plik, Nowy, projekt.

    Zostanie otwarte okno dialogowe Nowy projekt.

  3. W Szablonów okienka, wybierz polecenie języka Visual Basic lub Visual C#, a następnie wybierz polecenie Aplikacji WPF z listy typów projektów.

  4. W Nazwa tekst wprowadź AsyncExampleWPF, a następnie wybierz polecenie OK przycisk.

    W Eksploratorze rozwiązań pojawi się nowy projekt.

Aby zaprojektować proste MainWindow WPF

  1. Wybierz Visual Studio Edytor kodu, MainWindow.xaml kartę.

  2. Jeśli Przybornik okno nie jest widoczne, otwórz View menu, a następnie wybierz polecenie Przybornik.

  3. Dodać przycisk kontroli i pole tekstowe kontrolować do MainWindow okna.

  4. Podświetl pole tekstowe sterowania i w Właściwości okna, ustaw następujące wartości:

    • Ustaw Nazwa właściwość, aby resultsTextBox.

    • Ustaw Wysokość właściwość do 250.

    • Ustaw Szerokość właściwość do 500.

    • Na tekstu karta, określić czcionkę o stałej szerokości, takie jak Lucida Console lub globalnego o stałej szerokości.

  5. Podświetl przycisk sterowania i w Właściwości okna, ustaw następujące wartości:

    • Ustaw Nazwa właściwość, aby startButton.

    • Zmień wartość zawartości właściwość z przycisk do Start.

  6. Ustaw pole tekstowe i przycisk Tak, aby obie są wyświetlane w MainWindow okna.

    Aby uzyskać więcej informacji na temat programu WPF Designer XAML, zobacz Creating a UI by using XAML Designer.

Aby dodać odwołanie

  1. W Solution Explorer, wyróżnij nazwę projektu.

  2. Na pasku menu wybierz polecenie Projekt, Dodaj odwołanie.

    Reference Manager pojawi się okno dialogowe.

  3. U góry okna dialogowego Sprawdź, czy projekt jest kierowana 4.5.NET Framework.

  4. W zespoły obszar, wybierz polecenie Framework Jeśli nie jest jeszcze wybrana.

  5. Na liście nazwy, zaznacz System.Net.Http pole wyboru.

  6. Wybierz polecenie OK przycisk, aby zamknąć okno dialogowe.

Aby dodać niezbędne Imports instrukcje lub za pomocą dyrektyw

  1. W Solution Explorer, otwórz menu skrótów dla MainWindow.xaml.vb lub MainWindow.xaml.cs, a następnie wybierz View Code.

  2. Dodaj następujący Imports instrukcji (Visual Basic) lub using dyrektyw (C#) w górnej części pliku kodu, jeśli nie są już obecne.

    Imports System.Net.Http
    Imports System.Net
    Imports System.IO
    
    using System.Net.Http;
    using System.Net;
    using System.IO;
    

Aby utworzyć aplikację synchroniczne

  1. W oknie projektu, MainWindow.xaml, kliknij dwukrotnie Start przycisk, aby utworzyć startButton_Click Obsługa zdarzeń w MainWindow.xaml.vb lub MainWindow.xaml.cs.Jako alternatywę, podświetl Start przycisk, wybierz polecenie obsługę zdarzeń dla wybranych elementów ikonę w Właściwości okna, a następnie wprowadź startButton_Click w kliknij przycisk pole tekstowe.

  2. W MainWindow.xaml.vb lub MainWindow.xaml.cs, skopiuj następujący kod do treści startButton_Click.

    resultsTextBox.Clear()
    SumPageSizes()
    resultsTextBox.Text &= vbCrLf & "Control returned to startButton_Click."
    
    resultsTextBox.Clear();
    SumPageSizes();
    resultsTextBox.Text += "\r\nControl returned to startButton_Click.";
    

    Kod wywołuje metodę, która napędza aplikacji, SumPageSizesi wyświetla komunikat po przekazaniu sterowania do startButton_Click.

  3. Kod dla synchroniczne roztworu zawiera następujących metod:

    • SumPageSizes, który pobiera listę adresów URL strony sieci Web z SetUpURLList , a następnie wywołuje GetURLContents i DisplayResults do przetworzenia każdego adresu URL.

    • SetUpURLList, który sprawia, że i zwraca listę adresów sieci web.

    • GetURLContents, który pobiera zawartość każdej witryny sieci Web i zwraca zawartość jako tablicy bajtów.

    • DisplayResults, który wyświetla liczbę bajtów w tablicy bajtów dla każdego adresu URL.

    Skopiuj następujące cztery metody, a następnie wklejać je w obszarze startButton_Click Obsługa zdarzeń w MainWindow.xaml.vb lub MainWindow.xaml.cs.

    Private Sub SumPageSizes()
    
        ' Make a list of web addresses.
        Dim urlList As List(Of String) = SetUpURLList()
    
        Dim total = 0
        For Each url In urlList
            ' GetURLContents returns the contents of url as a byte array.
            Dim urlContents As Byte() = GetURLContents(url)
    
            DisplayResults(url, urlContents)
    
            ' Update the total.
            total += urlContents.Length
        Next
    
        ' Display the total count for all of the web addresses.
        resultsTextBox.Text &= String.Format(vbCrLf & vbCrLf & "Total bytes returned:  {0}" & vbCrLf, total)
    End Sub
    
    
    Private Function SetUpURLList() As List(Of String)
    
        Dim urls = New List(Of String) From
            {
                "https://msdn.microsoft.com/library/windows/apps/br211380.aspx",
                "https://msdn.microsoft.com",
                "https://msdn.microsoft.com/en-us/library/hh290136.aspx",
                "https://msdn.microsoft.com/en-us/library/ee256749.aspx",
                "https://msdn.microsoft.com/en-us/library/hh290138.aspx",
                "https://msdn.microsoft.com/en-us/library/hh290140.aspx",
                "https://msdn.microsoft.com/en-us/library/dd470362.aspx",
                "https://msdn.microsoft.com/en-us/library/aa578028.aspx",
                "https://msdn.microsoft.com/en-us/library/ms404677.aspx",
                "https://msdn.microsoft.com/en-us/library/ff730837.aspx"
            }
        Return urls
    End Function
    
    
    Private Function GetURLContents(url As String) As Byte()
    
        ' The downloaded resource ends up in the variable named content.
        Dim content = New MemoryStream()
    
        ' Initialize an HttpWebRequest for the current URL.
        Dim webReq = CType(WebRequest.Create(url), HttpWebRequest)
    
        ' Send the request to the Internet resource and wait for
        ' the response.
        Using response As WebResponse = webReq.GetResponse()
            ' Get the data stream that is associated with the specified URL.
            Using responseStream As Stream = response.GetResponseStream()
                ' Read the bytes in responseStream and copy them to content.  
                responseStream.CopyTo(content)
            End Using
        End Using
    
        ' Return the result as a byte array.
        Return content.ToArray()
    End Function
    
    
    Private Sub DisplayResults(url As String, content As Byte())
    
        ' Display the length of each website. The string format 
        ' is designed to be used with a monospaced font, such as
        ' Lucida Console or Global Monospace.
        Dim bytes = content.Length
        ' Strip off the "http://".
        Dim displayURL = url.Replace("http://", "")
        resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes)
    End Sub
    
    private void SumPageSizes()
    {
        // Make a list of web addresses.
        List<string> urlList = SetUpURLList(); 
    
        var total = 0;
        foreach (var url in urlList)
        {
            // GetURLContents returns the contents of url as a byte array.
            byte[] urlContents = GetURLContents(url);
    
            DisplayResults(url, urlContents);
    
            // Update the total.
            total += urlContents.Length;
        }
    
        // Display the total count for all of the web addresses.
        resultsTextBox.Text += 
            string.Format("\r\n\r\nTotal bytes returned:  {0}\r\n", total);
    }
    
    
    private List<string> SetUpURLList()
    {
        var urls = new List<string> 
        { 
            "https://msdn.microsoft.com/library/windows/apps/br211380.aspx",
            "https://msdn.microsoft.com",
            "https://msdn.microsoft.com/en-us/library/hh290136.aspx",
            "https://msdn.microsoft.com/en-us/library/ee256749.aspx",
            "https://msdn.microsoft.com/en-us/library/hh290138.aspx",
            "https://msdn.microsoft.com/en-us/library/hh290140.aspx",
            "https://msdn.microsoft.com/en-us/library/dd470362.aspx",
            "https://msdn.microsoft.com/en-us/library/aa578028.aspx",
            "https://msdn.microsoft.com/en-us/library/ms404677.aspx",
            "https://msdn.microsoft.com/en-us/library/ff730837.aspx"
        };
        return urls;
    }
    
    
    private byte[] GetURLContents(string url)
    {
        // The downloaded resource ends up in the variable named content.
        var content = new MemoryStream();
    
        // Initialize an HttpWebRequest for the current URL.
        var webReq = (HttpWebRequest)WebRequest.Create(url);
    
        // Send the request to the Internet resource and wait for
        // the response.
        using (WebResponse response = webReq.GetResponse())
        {
            // Get the data stream that is associated with the specified URL.
            using (Stream responseStream = response.GetResponseStream())
            {
                // Read the bytes in responseStream and copy them to content.  
                responseStream.CopyTo(content);
            }
        }
    
        // Return the result as a byte array.
        return content.ToArray();
    }
    
    
    private void DisplayResults(string url, byte[] content)
    {
        // Display the length of each website. The string format 
        // is designed to be used with a monospaced font, such as
        // Lucida Console or Global Monospace.
        var bytes = content.Length;
        // Strip off the "http://".
        var displayURL = url.Replace("http://", "");
        resultsTextBox.Text += string.Format("\n{0,-58} {1,8}", displayURL, bytes);
    }
    

Aby przetestować rozwiązanie synchroniczne

  • Wybierz klawisz F5, aby uruchomić program, a następnie wybierz Start przycisk.

    Powinien pojawić się dane wyjściowe podobne do poniższej listy.

    msdn.microsoft.com/library/windows/apps/br211380.aspx        383832
    msdn.microsoft.com                                            33964
    msdn.microsoft.com/en-us/library/hh290136.aspx               225793
    msdn.microsoft.com/en-us/library/ee256749.aspx               143577
    msdn.microsoft.com/en-us/library/hh290138.aspx               237372
    msdn.microsoft.com/en-us/library/hh290140.aspx               128279
    msdn.microsoft.com/en-us/library/dd470362.aspx               157649
    msdn.microsoft.com/en-us/library/aa578028.aspx               204457
    msdn.microsoft.com/en-us/library/ms404677.aspx               176405
    msdn.microsoft.com/en-us/library/ff730837.aspx               143474
    
    Total bytes returned:  1834802
    
    Control returned to startButton_Click.
    

    Należy zauważyć, że trwa kilka sekund, aby wyświetlić liczby elementów.W tym czasie wątek interfejsu użytkownika jest blokowany podczas oczekiwania na żądane zasoby do pobrania.W rezultacie nie można przenosić, zmaksymalizować, zminimalizować lub nawet zamknąć okna ekran, po wybraniu Start przycisk.Te metody zawiodą, aż liczników bajtów zaczną się pojawiać.Jeśli witryna sieci Web nie odpowiada, masz żadnego wskazania jakiej strony nie powiodło się.Trudno nawet zatrzymać oczekiwania i zamknąć program.

    Porównaj ten problem i Przykład do asynchronicznego rozwiązania.

Aby przekonwertować do asynchronicznej metody GetURLContents

  1. Aby przekonwertować synchroniczne roztwór do asynchronicznego rozwiązania, najlepiej zacząć jest w GetURLContents ponieważ połączeń w celu HttpWebRequest metoda GetResponse i Stream metoda CopyTo są, gdzie aplikacja uzyskuje dostęp do sieci web..NET Framework ułatwia konwersję poprzez dostarczanie asynchroniczne wersji obu metod.

    Aby uzyskać więcej informacji na temat metod, które są używane w GetURLContents, zobacz WebRequest.

    [!UWAGA]

    Wykonując kroki opisane w tym instruktażu są wyświetlane kilka błędy kompilatora.Można je zignorować i kontynuować instruktażu.

    Zmienić metodę, która jest wywoływana w trzecim wierszu GetURLContents z GetResponse do asynchronicznego, związanych z zadaniami GetResponseAsync metoda.

    Using response As WebResponse = webReq.GetResponseAsync()
    
    using (WebResponse response = webReq.GetResponseAsync())
    
  2. GetResponseAsyncZwraca Task<TResult>.W takim przypadku zadanie zwracać zmienną, TResult, ma typ WebResponse.Zadanie jest obietnicą do produkcji rzeczywistej WebResponse obiekt po pobraniu żądanych danych i zadanie ma być uruchomione do zakończenia.

    Pobrać WebResponse wartości od zadania, stosowanie oczekiwać (Visual Basic) lub czekają na operatora (C#) na wezwanie do GetResponseAsync, jak w poniższym kodzie pokazano.

    Using response As WebResponse = Await webReq.GetResponseAsync()
    
    using (WebResponse response = await webReq.GetResponseAsync())
    

    Operator oczekiwać zawiesza wykonywanie bieżącej metody, GetURLContents, dopóki nie oczekiwany zadanie zostało wykonane.W międzyczasie zwraca sterowania do wywołującego bieżącej metody.W tym przykładzie jest bieżącą metodę GetURLContents, a obiekt wywołujący jest SumPageSizes.Kiedy zadanie jest gotowy, obiecał WebResponse obiektu jest jako wartość oczekiwana zadań oraz przypisywanie do zmiennej response.

    Poprzednia można podzielić na dwie poniższe instrukcje wyjaśnienie, co się dzieje.

    'Dim responseTask As Task(Of WebResponse) = webReq.GetResponseAsync()
    'Using response As WebResponse = Await responseTask
    
    //Task<WebResponse> responseTask = webReq.GetResponseAsync();
    //using (WebResponse response = await responseTask)
    

    The call to webReq.GetResponseAsync returns a Task(Of WebResponse) or Task<WebResponse>.Następnie operator oczekiwać jest stosowany do zadania, aby pobrać WebResponse wartość.

    Jeśli Twoja forma komunikacji asynchronicznej ma robić prace, która nie polega na wykonaniu zadania, metodę można kontynuować tej pracy miedzy dwiema instrukcjami, po wywołaniu metody asynchronicznej i przed zastosowaniem operatora oczekiwać.Przykłady, zobacz Jak: tworzenie wielu sieci Web żądania równolegle (C# i Visual Basic) i Jak: rozszerzenie Instruktaż przy użyciu Task.WhenAll (C# i Visual Basic).

  3. Ponieważ dodano Await lub await wystąpi błąd kompilatora operatora w poprzednim kroku.Operator może być używany tylko w metodach, które oznaczono za pomocą asynchroniczne (Visual Basic) lub asynchroniczne modyfikator (C#).Zignorować błąd, podczas gdy Powtórz kroki konwersji, aby zastąpić wywołanie CopyTo z wezwaniem do CopyToAsync.

    • Zmienić nazwę metody, która jest wywoływana w celu CopyToAsync.

    • CopyTo Lub CopyToAsync metoda kopiuje bajty do argumentu, contenti nie zwraca wartości znaczące.W wersji synchroniczne, wywołanie CopyTo jest prostą instrukcję, która nie zwraca wartości.Wersja asynchronicznych, CopyToAsync, zwraca Task.Zadanie funkcje, takie jak "Task(void)" i umożliwia metodę, która ma być oczekiwany.Zastosowanie Await lub await na wezwanie do CopyToAsync, jak w poniższym kodzie pokazano.

      Await responseStream.CopyToAsync(content)
      
      await responseStream.CopyToAsync(content);
      

      Poprzednia Wyświetla trzyliterowy skrót następujące dwa wiersze kodu.

      ' CopyToAsync returns a Task, not a Task<T>.
      'Dim copyTask As Task = responseStream.CopyToAsync(content)
      
      ' When copyTask is completed, content contains a copy of
      ' responseStream.
      'Await copyTask
      
      // CopyToAsync returns a Task, not a Task<T>.
      //Task copyTask = responseStream.CopyToAsync(content);
      
      // When copyTask is completed, content contains a copy of
      // responseStream.
      //await copyTask;
      
  4. Wszystko, co pozostaje do zrobienia w GetURLContents ma na celu dostosowanie podpis metody.Można użyć Await lub await operatora tylko w metodach, które oznaczono za pomocą asynchroniczne (Visual Basic) lub asynchroniczne modyfikator (C#).Modyfikator do oznaczania metody jako metody asynchronicznej, jak w poniższym kodzie pokazano.

    Private Async Function GetURLContents(url As String) As Byte()
    
    private async byte[] GetURLContents(string url)
    
  5. Zwracany typ metody asynchronicznej można tylko Task, Task<TResult>, lub void w języku C#.W języku Visual Basic, metoda musi być Function , które przekazuje Task lub Task(Of T), lub metoda musi być Sub.Zazwyczaj Sub metody (Visual Basic) lub typem zwracanym przez void (C#) jest używany tylko w obsłudze zdarzeń asynchronicznych, gdzie Sub lub void jest wymagana.W pozostałych przypadkach, korzystamy z Task(T) Jeśli wypełniony metoda ma powrócić lub powrócić instrukcji, która zwraca wartość typu T i używasz Task Jeśli wypełniony metoda nie zwraca wartości znaczące.Możesz myśleć o Task zwracany typ jako oznaczające "Task(void)".

    Aby uzyskać więcej informacji, zobacz Typy zwrotu Async (C# i Visual Basic).

    Metoda GetURLContents ma instrukcję return, a instrukcja zwraca tablicy bajtów.W związku z tym zwracany typ wersji komunikacji asynchronicznej jest Task(T), gdzie T jest tablica bajtów.W podpisie metody, należy wprowadzić następujące zmiany:

    • Zmień typ zwracany do Task(Of Byte()) (Visual Basic) lub Task<byte[]> (C#).

    • Umownie, metody asynchronicznego mają nazwy, które kończą się na "Komunikacji asynchronicznej," tak zmień nazwę metody GetURLContentsAsync.

    Poniższy kod przedstawia te zmiany.

    Private Async Function GetURLContentsAsync(url As String) As Task(Of Byte())
    
    private async Task<byte[]> GetURLContentsAsync(string url)
    

    Z tych kilku zmian, przeliczenie GetURLContents do asynchronicznej metody jest kompletny.

Aby przekonwertować do asynchronicznej metody SumPageSizes

  1. Powtórz kroki od poprzedniej procedury dla SumPageSizes.Najpierw należy zmienić wywołanie GetURLContents do wywołanie asynchroniczne.

    • Zmienić nazwę metody, która jest wywoływana z GetURLContents do GetURLContentsAsync, jeśli nie zostało jeszcze zrobione.

    • Zastosowanie Await lub await do zadania, GetURLContentsAsync powoduje powrót do uzyskania bajt tablicy wartości.

    Poniższy kod przedstawia te zmiany.

    Dim urlContents As Byte() = Await GetURLContentsAsync(url)
    
    byte[] urlContents = await GetURLContentsAsync(url);
    

    Poprzednie przypisania Wyświetla trzyliterowy skrót następujące dwa wiersze kodu.

    ' GetURLContentsAsync returns a task. At completion, the task
    ' produces a byte array.
    'Dim getContentsTask As Task(Of Byte()) = GetURLContentsAsync(url)
    'Dim urlContents As Byte() = Await getContentsTask
    
    // GetURLContentsAsync returns a Task<T>. At completion, the task
    // produces a byte array.
    //Task<byte[]> getContentsTask = GetURLContentsAsync(url);
    //byte[] urlContents = await getContentsTask;
    
  2. W podpisie tej metody, należy wprowadzić następujące zmiany:

    • Oznaczyć metody z Async lub async modyfikator.

    • Dodaj "Async" do nazwy metody.

    • Nie jest Brak zadań zwracać zmienną, T, tym razem, ponieważ SumPageSizesAsync nie zwraca wartości dla T.(Metoda nie ma Return lub return instrukcja.) Jednak metoda musi zwracać Task się awaitable.W związku z tym wprowadzić następujące zmiany:

      • W języku Visual Basic, należy zmienić typ metody z Sub do Function.Zwracany typ funkcji jest Task.

      • W języku C#, zmienić zwrotu typu metody z void do Task.

    Poniższy kod przedstawia te zmiany.

    Private Async Function SumPageSizesAsync() As Task
    
    private async Task SumPageSizesAsync()
    

    Konwersja z SumPageSizes do SumPageSizesAsync została zakończona.

Aby przekonwertować do asynchronicznej metody startButton_Click

  1. W procedurze obsługi zdarzenia, należy zmienić nazwę metody o nazwie od SumPageSizes do SumPageSizesAsync, jeśli nie zostało jeszcze zrobione.

  2. Ponieważ SumPageSizesAsync jest metodą komunikacji asynchronicznej, Zmień kod w procedurze obsługi zdarzenia poczekać wynik.

    Wywołanie SumPageSizesAsync odzwierciedla wywołanie CopyToAsync w GetURLContentsAsync.Wywołanie zwraca Task, a nie Task(T).

    Tak jak w poprzedniej procedury można przekonwertować wywołanie przy użyciu jednej instrukcji lub dwie instrukcje.Poniższy kod przedstawia te zmiany.

    '' One-step async call.
    Await SumPageSizesAsync()
    
    ' Two-step async call.
    'Dim sumTask As Task = SumPageSizesAsync()
    'Await sumTask
    
    // One-step async call.
    await SumPageSizesAsync();
    
    // Two-step async call.
    //Task sumTask = SumPageSizesAsync();
    //await sumTask;
    
  3. Aby zapobiec przypadkowemu ponownego wprowadzania operacji, należy dodać następującą instrukcję w górnej części startButton_Click Aby wyłączyć Start przycisk.

    ' Disable the button until the operation is complete.
    startButton.IsEnabled = False
    
    // Disable the button until the operation is complete.
    startButton.IsEnabled = false;
    

    Można ponownie włączyć przycisk na końcu programu obsługi zdarzeń.

    ' Reenable the button in case you want to run the operation again.
    startButton.IsEnabled = True
    
    // Reenable the button in case you want to run the operation again.
    startButton.IsEnabled = true;
    

    Aby uzyskać więcej informacji na temat ponownego rozpoczęcia, zobacz Obsługa ponownego rozpoczęcia w aplikacjach asynchronicznych (C# i Visual Basic).

  4. Na koniec należy dodać Async lub async modyfikator do deklaracji tak, że program obsługi zdarzeń można poczekać na SumPagSizesAsync.

    Async Sub startButton_Click(sender As Object, e As RoutedEventArgs) Handles startButton.Click
    
    private async void startButton_Click(object sender, RoutedEventArgs e)
    

    Zazwyczaj nazwy procedury obsługi zdarzeń nie są zmienione.Zwracany typ nie zmienia się, aby Task ponieważ programy obsługi zdarzeń musi zwracać void w języku C# lub być Sub w języku Visual Basic.W związku z tym, typ zwracany do Task.

    Konwersja projektu z przetwarzania synchroniczne i asynchroniczne została zakończona.

Aby przetestować rozwiązania asynchroniczne

  1. Wybierz klawisz F5, aby uruchomić program, a następnie wybierz Start przycisk.

  2. Dane wyjściowe podobne dane wyjściowe synchroniczne rozwiązanie powinno być widoczne.Jednakże zauważyć następujące różnice.

    • Wszystkie wyniki nie występują w tym samym czasie, po zakończeniu przetwarzania.Na przykład, oba programy zawierają linii w startButton_Click który czyści pole tekstowe.Wprowadza do celu wyczyść pole tekst między działa, jeśli wybierzesz Start przycisk po raz drugi, po pojawił się jeden zestaw wyników.W wersji synchroniczne pole tekstowe jest wyczyszczone, tuż przed liczy pojawiają się po raz drugi, kiedy wykonywane są pliki do pobrania i wątku interfejsu użytkownika jest wolna na wykonywanie innych czynności.W asynchronicznej wersji pola tekstowego powoduje wyczyszczenie natychmiast po dokonaniu wyboru Start przycisk.

    • Co najważniejsze wątek interfejsu użytkownika nie jest blokowane podczas pliki do pobrania.Można przenieść lub zmienić rozmiar okna, podczas gdy w trakcie pobierania zasobów sieci web, liczą się i wyświetlane.Jeśli jedną z witryn sieci Web jest wolne lub nie odpowiada, można anulować tę operację, wybierz polecenie Zamknij button (przycisk x w czerwonym polu w prawym górnym rogu).

Aby zastąpić metodę GetURLContentsAsync metoda.NET Framework

  1. 4.5.NET Framework zapewnia wiele metod komunikacji asynchronicznej, które można użyć.Jeden z nich, HttpClient metoda GetByteArrayAsync(String), czy to, czego potrzebujesz do wykonania tej procedury.Dzięki niemu można zamiast GetURLContentsAsync metoda utworzonego wcześniej w procedurze.

    Pierwszym krokiem jest utworzenie HttpClient obiektu w metodzie SumPageSizesAsync.Dodaj następującą deklarację, na początku metody.

    ' Declare an HttpClient object and increase the buffer size. The
    ' default buffer size is 65,536.
    Dim client As HttpClient =
        New HttpClient() With {.MaxResponseContentBufferSize = 1000000}
    
    // Declare an HttpClient object and increase the buffer size. The
    // default buffer size is 65,536.
    HttpClient client =
        new HttpClient() { MaxResponseContentBufferSize = 1000000 };
    
  2. W SumPageSizesAsync, zastąpić wywołanie Twój GetURLContentsAsync metoda z wezwaniem do HttpClient metoda.

    Dim urlContents As Byte() = Await client.GetByteArrayAsync(url)
    
    byte[] urlContents = await client.GetByteArrayAsync(url);               
    
  3. Usunąć lub skomentować GetURLContentsAsync metodę, która zostało napisane.

  4. Wybierz klawisz F5, aby uruchomić program, a następnie wybierz Start przycisk.

    Zachowanie tej wersji projektu powinien zachowania, która opisuje procedurę "Aby asynchronicznego roztworu badanego", ale z nawet mniej wysiłku od Ciebie.

Przykład

Poniższy kod zawiera pełny przykład konwersja z synchronicznego asynchronicznego roztwór przy użyciu asynchronicznej GetURLContentsAsync metodę, która zostało napisane.Zawiadomienie o zdecydowanie przypomina rozwiązanie oryginalnego, synchroniczne.

' Add the following Imports statements, and add a reference for System.Net.Http.
Imports System.Net.Http
Imports System.Net
Imports System.IO

Class MainWindow

    Async Sub startButton_Click(sender As Object, e As RoutedEventArgs) Handles startButton.Click

        ' Disable the button until the operation is complete.
        startButton.IsEnabled = False

        resultsTextBox.Clear()

        '' One-step async call.
        Await SumPageSizesAsync()

        ' Two-step async call.
        'Dim sumTask As Task = SumPageSizesAsync()
        'Await sumTask

        resultsTextBox.Text &= vbCrLf & "Control returned to button1_Click."

        ' Reenable the button in case you want to run the operation again.
        startButton.IsEnabled = True
    End Sub


    Private Async Function SumPageSizesAsync() As Task

        ' Make a list of web addresses.
        Dim urlList As List(Of String) = SetUpURLList()

        Dim total = 0
        For Each url In urlList
            Dim urlContents As Byte() = Await GetURLContentsAsync(url)

            ' The previous line abbreviates the following two assignment statements.

            ' GetURLContentsAsync returns a task. At completion, the task
            ' produces a byte array.
            'Dim getContentsTask As Task(Of Byte()) = GetURLContentsAsync(url)
            'Dim urlContents As Byte() = Await getContentsTask

            DisplayResults(url, urlContents)

            ' Update the total.
            total += urlContents.Length
        Next

        ' Display the total count for all of the websites.
        resultsTextBox.Text &= String.Format(vbCrLf & vbCrLf &
                                             "Total bytes returned:  {0}" & vbCrLf, total)
    End Function


    Private Function SetUpURLList() As List(Of String)

        Dim urls = New List(Of String) From
            {
                "https://msdn.microsoft.com/library/windows/apps/br211380.aspx",
                "https://msdn.microsoft.com",
                "https://msdn.microsoft.com/en-us/library/hh290136.aspx",
                "https://msdn.microsoft.com/en-us/library/ee256749.aspx",
                "https://msdn.microsoft.com/en-us/library/hh290138.aspx",
                "https://msdn.microsoft.com/en-us/library/hh290140.aspx",
                "https://msdn.microsoft.com/en-us/library/dd470362.aspx",
                "https://msdn.microsoft.com/en-us/library/aa578028.aspx",
                "https://msdn.microsoft.com/en-us/library/ms404677.aspx",
                "https://msdn.microsoft.com/en-us/library/ff730837.aspx"
            }
        Return urls
    End Function


    Private Async Function GetURLContentsAsync(url As String) As Task(Of Byte())

        ' The downloaded resource ends up in the variable named content.
        Dim content = New MemoryStream()

        ' Initialize an HttpWebRequest for the current URL.
        Dim webReq = CType(WebRequest.Create(url), HttpWebRequest)

        ' Send the request to the Internet resource and wait for
        ' the response.
        Using response As WebResponse = Await webReq.GetResponseAsync()

            ' The previous statement abbreviates the following two statements.

            'Dim responseTask As Task(Of WebResponse) = webReq.GetResponseAsync()
            'Using response As WebResponse = Await responseTask

            ' Get the data stream that is associated with the specified URL.
            Using responseStream As Stream = response.GetResponseStream()
                ' Read the bytes in responseStream and copy them to content.  
                Await responseStream.CopyToAsync(content)

                ' The previous statement abbreviates the following two statements.

                ' CopyToAsync returns a Task, not a Task<T>.
                'Dim copyTask As Task = responseStream.CopyToAsync(content)

                ' When copyTask is completed, content contains a copy of
                ' responseStream.
                'Await copyTask
            End Using
        End Using

        ' Return the result as a byte array.
        Return content.ToArray()
    End Function


    Private Sub DisplayResults(url As String, content As Byte())

        ' Display the length of each website. The string format 
        ' is designed to be used with a monospaced font, such as
        ' Lucida Console or Global Monospace.
        Dim bytes = content.Length
        ' Strip off the "http://".
        Dim displayURL = url.Replace("http://", "")
        resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes)
    End Sub

End Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

// Add the following using directives, and add a reference for System.Net.Http.
using System.Net.Http;
using System.IO;
using System.Net;

namespace AsyncExampleWPF
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private async void startButton_Click(object sender, RoutedEventArgs e)
        {
            // Disable the button until the operation is complete.
            startButton.IsEnabled = false;

            resultsTextBox.Clear();

            // One-step async call.
            await SumPageSizesAsync();

            // Two-step async call.
            //Task sumTask = SumPageSizesAsync();
            //await sumTask;

            resultsTextBox.Text += "\r\nControl returned to startButton_Click.\r\n";

            // Reenable the button in case you want to run the operation again.
            startButton.IsEnabled = true;
        }


        private async Task SumPageSizesAsync()
        {
            // Make a list of web addresses.
            List<string> urlList = SetUpURLList();

            var total = 0;

            foreach (var url in urlList)
            {
                byte[] urlContents = await GetURLContentsAsync(url);

                // The previous line abbreviates the following two assignment statements.

                // GetURLContentsAsync returns a Task<T>. At completion, the task
                // produces a byte array.
                //Task<byte[]> getContentsTask = GetURLContentsAsync(url);
                //byte[] urlContents = await getContentsTask;

                DisplayResults(url, urlContents);

                // Update the total.          
                total += urlContents.Length;
            }
            // Display the total count for all of the websites.
            resultsTextBox.Text +=
                string.Format("\r\n\r\nTotal bytes returned:  {0}\r\n", total);
        }


        private List<string> SetUpURLList()
        {
            List<string> urls = new List<string> 
            { 
                "https://msdn.microsoft.com/library/windows/apps/br211380.aspx",
                "https://msdn.microsoft.com",
                "https://msdn.microsoft.com/en-us/library/hh290136.aspx",
                "https://msdn.microsoft.com/en-us/library/ee256749.aspx",
                "https://msdn.microsoft.com/en-us/library/hh290138.aspx",
                "https://msdn.microsoft.com/en-us/library/hh290140.aspx",
                "https://msdn.microsoft.com/en-us/library/dd470362.aspx",
                "https://msdn.microsoft.com/en-us/library/aa578028.aspx",
                "https://msdn.microsoft.com/en-us/library/ms404677.aspx",
                "https://msdn.microsoft.com/en-us/library/ff730837.aspx"
            };
            return urls;
        }


        private async Task<byte[]> GetURLContentsAsync(string url)
        {
            // The downloaded resource ends up in the variable named content.
            var content = new MemoryStream();

            // Initialize an HttpWebRequest for the current URL.
            var webReq = (HttpWebRequest)WebRequest.Create(url);

            // Send the request to the Internet resource and wait for
            // the response.                
            using (WebResponse response = await webReq.GetResponseAsync())

            // The previous statement abbreviates the following two statements.

            //Task<WebResponse> responseTask = webReq.GetResponseAsync();
            //using (WebResponse response = await responseTask)
            {
                // Get the data stream that is associated with the specified url.
                using (Stream responseStream = response.GetResponseStream())
                {
                    // Read the bytes in responseStream and copy them to content. 
                    await responseStream.CopyToAsync(content);

                    // The previous statement abbreviates the following two statements.

                    // CopyToAsync returns a Task, not a Task<T>.
                    //Task copyTask = responseStream.CopyToAsync(content);

                    // When copyTask is completed, content contains a copy of
                    // responseStream.
                    //await copyTask;
                }
            }
            // Return the result as a byte array.
            return content.ToArray();
        }


        private void DisplayResults(string url, byte[] content)
        {
            // Display the length of each website. The string format 
            // is designed to be used with a monospaced font, such as
            // Lucida Console or Global Monospace.
            var bytes = content.Length;
            // Strip off the "http://".
            var displayURL = url.Replace("http://", "");
            resultsTextBox.Text += string.Format("\n{0,-58} {1,8}", displayURL, bytes);
        }
    }
}

Poniższy kod zawiera pełny przykład rozwiązania, korzystającego z HttpClient metodę, GetByteArrayAsync.

' Add the following Imports statements, and add a reference for System.Net.Http.
Imports System.Net.Http
Imports System.Net
Imports System.IO

Class MainWindow

    Async Sub startButton_Click(sender As Object, e As RoutedEventArgs) Handles startButton.Click

        resultsTextBox.Clear()

        ' Disable the button until the operation is complete.
        startButton.IsEnabled = False

        ' One-step async call.
        Await SumPageSizesAsync()

        '' Two-step async call.
        'Dim sumTask As Task = SumPageSizesAsync()
        'Await sumTask

        resultsTextBox.Text &= vbCrLf & "Control returned to button1_Click."

        ' Reenable the button in case you want to run the operation again.
        startButton.IsEnabled = True
    End Sub


    Private Async Function SumPageSizesAsync() As Task

        ' Declare an HttpClient object and increase the buffer size. The
        ' default buffer size is 65,536.
        Dim client As HttpClient =
            New HttpClient() With {.MaxResponseContentBufferSize = 1000000}

        ' Make a list of web addresses.
        Dim urlList As List(Of String) = SetUpURLList()

        Dim total = 0
        For Each url In urlList
            ' GetByteArrayAsync returns a task. At completion, the task
            ' produces a byte array.
            Dim urlContents As Byte() = Await client.GetByteArrayAsync(url)

            ' The following two lines can replace the previous assignment statement.
            'Dim getContentsTask As Task(Of Byte()) = client.GetByteArrayAsync(url)
            'Dim urlContents As Byte() = Await getContentsTask

            DisplayResults(url, urlContents)

            ' Update the total.
            total += urlContents.Length
        Next

        ' Display the total count for all of the websites.
        resultsTextBox.Text &= String.Format(vbCrLf & vbCrLf &
                                             "Total bytes returned:  {0}" & vbCrLf, total)
    End Function


    Private Function SetUpURLList() As List(Of String)

        Dim urls = New List(Of String) From
            {
                "https://msdn.microsoft.com/library/windows/apps/br211380.aspx",
                "https://msdn.microsoft.com",
                "https://msdn.microsoft.com/en-us/library/hh290136.aspx",
                "https://msdn.microsoft.com/en-us/library/ee256749.aspx",
                "https://msdn.microsoft.com/en-us/library/hh290138.aspx",
                "https://msdn.microsoft.com/en-us/library/hh290140.aspx",
                "https://msdn.microsoft.com/en-us/library/dd470362.aspx",
                "https://msdn.microsoft.com/en-us/library/aa578028.aspx",
                "https://msdn.microsoft.com/en-us/library/ms404677.aspx",
                "https://msdn.microsoft.com/en-us/library/ff730837.aspx"
            }
        Return urls
    End Function


    Private Sub DisplayResults(url As String, content As Byte())

        ' Display the length of each website. The string format 
        ' is designed to be used with a monospaced font, such as
        ' Lucida Console or Global Monospace.
        Dim bytes = content.Length
        ' Strip off the "http://".
        Dim displayURL = url.Replace("http://", "")
        resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes)
    End Sub

End Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

// Add the following using directives, and add a reference for System.Net.Http.
using System.Net.Http;
using System.IO;
using System.Net;


namespace AsyncExampleWPF
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private async void startButton_Click(object sender, RoutedEventArgs e)
        {
            resultsTextBox.Clear();

            // Disable the button until the operation is complete.
            startButton.IsEnabled = false;

            // One-step async call.
            await SumPageSizesAsync();

            //// Two-step async call.
            //Task sumTask = SumPageSizesAsync();
            //await sumTask;

            resultsTextBox.Text += "\r\nControl returned to startButton_Click.\r\n";

            // Reenable the button in case you want to run the operation again.
            startButton.IsEnabled = true;
        }


        private async Task SumPageSizesAsync()
        {
            // Declare an HttpClient object and increase the buffer size. The
            // default buffer size is 65,536.
            HttpClient client =
                new HttpClient() { MaxResponseContentBufferSize = 1000000 };

            // Make a list of web addresses.
            List<string> urlList = SetUpURLList();

            var total = 0;

            foreach (var url in urlList)
            {
                // GetByteArrayAsync returns a task. At completion, the task
                // produces a byte array.
                byte[] urlContents = await client.GetByteArrayAsync(url);               

                // The following two lines can replace the previous assignment statement.
                //Task<byte[]> getContentsTask = client.GetByteArrayAsync(url);
                //byte[] urlContents = await getContentsTask;

                DisplayResults(url, urlContents);

                // Update the total.
                total += urlContents.Length;
            }

            // Display the total count for all of the websites.
            resultsTextBox.Text +=
                string.Format("\r\n\r\nTotal bytes returned:  {0}\r\n", total);
        }


        private List<string> SetUpURLList()
        {
            List<string> urls = new List<string> 
            { 
                "https://msdn.microsoft.com/library/windows/apps/br211380.aspx",
                "https://msdn.microsoft.com",
                "https://msdn.microsoft.com/en-us/library/hh290136.aspx",
                "https://msdn.microsoft.com/en-us/library/ee256749.aspx",
                "https://msdn.microsoft.com/en-us/library/hh290138.aspx",
                "https://msdn.microsoft.com/en-us/library/hh290140.aspx",
                "https://msdn.microsoft.com/en-us/library/dd470362.aspx",
                "https://msdn.microsoft.com/en-us/library/aa578028.aspx",
                "https://msdn.microsoft.com/en-us/library/ms404677.aspx",
                "https://msdn.microsoft.com/en-us/library/ff730837.aspx"
            };
            return urls;
        }


        private void DisplayResults(string url, byte[] content)
        {
            // Display the length of each website. The string format 
            // is designed to be used with a monospaced font, such as
            // Lucida Console or Global Monospace.
            var bytes = content.Length;
            // Strip off the "http://".
            var displayURL = url.Replace("http://", "");
            resultsTextBox.Text += string.Format("\n{0,-58} {1,8}", displayURL, bytes);
        }
    }
}

Zobacz też

Zadania

Jak: rozszerzenie Instruktaż przy użyciu Task.WhenAll (C# i Visual Basic)

Jak: tworzenie wielu sieci Web żądania równolegle (C# i Visual Basic)

Wskazówki: Korzystanie z debugera i metod asynchronicznych

Informacje

Asynchroniczne (C# odniesienia)

poczekać (C# odniesienia)

Poczekać operatora (Visual Basic)

Asynchroniczne (Visual Basic)

Koncepcje

Asynchroniczne programowania przy użyciu asynchronicznej i poczekać (C# i Visual Basic)

Typy zwrotu Async (C# i Visual Basic)

Użycie Async do uzyskiwania dostępu do plików (C# i Visual Basic)

Inne zasoby

Próbka asynchroniczne: Dostęp do Przewodnik po składnikach Web (C# i Visual Basic)

, Związanych z zadaniami asynchronicznego programowania (TAP)

Szybki Start: za pomocą operatora oczekiwać dla asynchronicznego programowania,