Udostępnij za pośrednictwem


Obsługa ponownego rozpoczęcia w aplikacjach asynchronicznych (C# i Visual Basic)

Po dołączeniu asynchronicznego kodu aplikacji, należy wziąć pod uwagę i ewentualnie zapobiec ponownego rozpoczęcia, która odnosi się do ponownego wprowadzania operację asynchroniczną, zanim zostanie ukończona.Jeśli nie rozpoznać i obsłużyć możliwości współużytkowania wątkowości, może spowodować nieoczekiwane rezultaty.

W tym temacie

[!UWAGA]

Instrukcje w Przeglądanie i uruchamianie aplikacji przykładu pokazać, jak uruchomić kod w aplikacji Windows Presentation Foundation (WPF) lub jako aplikacji magazynu systemu Windows.

Aby uruchomić przykład w aplikacji WPF, musisz mieć program Visual Studio 2012 r., programu Visual Studio Express 2012 dla pulpitu systemu Windows, lub 4.5.NET Framework zainstalowana na komputerze.

Aby uruchomić przykład jako Windows Store aplikacji, musisz mieć 8 Windows zainstalowany na komputerze.Ponadto, jeśli chcesz uruchomić przykład z programu Visual Studio, trzeba mieć również Visual Studio 2012 lub programu Visual Studio Express 2012 dla Windows 8 zainstalowane.

UZNAJĄC współużytkowania wątkowości

W przykładzie w tym temacie, wybierz polecenie Użytkownicy Start przycisk do inicjowania asynchronicznego aplikacji, które pliki do pobrania szereg witryn sieci Web i oblicza całkowitą liczbę bajtów, które zostały pobrane.Synchroniczną wersję przykładu odpowie taki sam sposób niezależnie od tego ile razy użytkownik wybierze przycisk, ponieważ po raz pierwszy, wątek interfejsu użytkownika ignoruje te zdarzenia, dopóki nie zakończy się uruchamianie aplikacji.W asynchronicznej aplikacji należy jednak wątek interfejsu użytkownika będzie odpowiadać i może ponownie wprowadzić operacja asynchroniczna, zanim zostanie ukończona.

W poniższym przykładzie pokazano oczekiwanej wyjście, jeśli użytkownik zdecyduje się na Start przycisk tylko raz.Zostanie wyświetlona lista pobranych stron internetowych z rozmiar w bajtach, w każdym miejscu.Całkowita liczba bajtów pojawia się na końcu.

1. msdn.microsoft.com/en-us/library/hh191443.aspx                83732
2. msdn.microsoft.com/en-us/library/aa578028.aspx               205273
3. msdn.microsoft.com/en-us/library/jj155761.aspx                29019
4. msdn.microsoft.com/en-us/library/hh290140.aspx               117152
5. msdn.microsoft.com/en-us/library/hh524395.aspx                68959
6. msdn.microsoft.com/en-us/library/ms404677.aspx               197325
7. msdn.microsoft.com                                            42972
8. msdn.microsoft.com/en-us/library/ff730837.aspx               146159

TOTAL bytes returned:  890591

Jednak jeśli użytkownik wybierze przycisk więcej niż jeden raz, obsługa zdarzeń jest wywoływany cyklicznie, a proces pobierania jest ponownie wprowadzić każdorazowo.W efekcie kilka operacji asynchronicznych są uruchomione w tym samym czasie, dane wyjściowe przeplata wyniki i całkowita liczba bajtów jest mylące.

1. msdn.microsoft.com/en-us/library/hh191443.aspx                83732
2. msdn.microsoft.com/en-us/library/aa578028.aspx               205273
3. msdn.microsoft.com/en-us/library/jj155761.aspx                29019
4. msdn.microsoft.com/en-us/library/hh290140.aspx               117152
5. msdn.microsoft.com/en-us/library/hh524395.aspx                68959
1. msdn.microsoft.com/en-us/library/hh191443.aspx                83732
2. msdn.microsoft.com/en-us/library/aa578028.aspx               205273
6. msdn.microsoft.com/en-us/library/ms404677.aspx               197325
3. msdn.microsoft.com/en-us/library/jj155761.aspx                29019
7. msdn.microsoft.com                                            42972
4. msdn.microsoft.com/en-us/library/hh290140.aspx               117152
8. msdn.microsoft.com/en-us/library/ff730837.aspx               146159

TOTAL bytes returned:  890591

5. msdn.microsoft.com/en-us/library/hh524395.aspx                68959
1. msdn.microsoft.com/en-us/library/hh191443.aspx                83732
2. msdn.microsoft.com/en-us/library/aa578028.aspx               205273
6. msdn.microsoft.com/en-us/library/ms404677.aspx               197325
3. msdn.microsoft.com/en-us/library/jj155761.aspx                29019
4. msdn.microsoft.com/en-us/library/hh290140.aspx               117152
7. msdn.microsoft.com                                            42972
5. msdn.microsoft.com/en-us/library/hh524395.aspx                68959
8. msdn.microsoft.com/en-us/library/ff730837.aspx               146159

TOTAL bytes returned:  890591

6. msdn.microsoft.com/en-us/library/ms404677.aspx               197325
7. msdn.microsoft.com                                            42972
8. msdn.microsoft.com/en-us/library/ff730837.aspx               146159

TOTAL bytes returned:  890591

Możesz przejrzeć kod, który generuje ten dane wyjściowe za pomocą przewijania na końcu tego tematu.Można eksperymentować z kodem pobierania roztwór na komputerze lokalnym, a następnie uruchamiając projektu WebsiteDownload lub przy użyciu kodu na końcu tego tematu do utworzenia własnego projektu, aby uzyskać więcej informacji i uzyskać instrukcje, zobacz Przeglądanie i uruchamianie aplikacji przykładu.

Obsługiwanie współużytkowania wątkowości

Można obsługiwać współużytkowania wątkowości w na różne sposoby, w zależności od tego, co chcesz robić Twoja aplikacja.W tym temacie przedstawiono następujące przykłady:

  • Wyłącz przycisk Start

    Wyłącz Start przycisk podczas operacji jest uruchomiony, tak aby użytkownik nie może przerwać to.

  • Anuluj i ponownie uruchomić operację

    Anulować wszelkie operacje, które nadal działa, gdy użytkownik zdecyduje się na Start przycisk ponownie, a następnie kontynuuj Niech najbardziej niedawno żądanej operacji.

  • Uruchamianie wielu operacji i dane wyjściowe w kolejce

    Zezwalaj na wszystkich wymaganych czynności do wykonania asynchronicznie, ale koordynować sposobu wyświetlania danych wyjściowych, tak aby były wyświetlane wyniki z każdej operacji, ze sobą i w kolejności.

JJ651641.collapse_all(pl-pl,VS.110).gifWyłącz przycisk Start

Można zablokować Start przycisk po uruchomieniu operacji poprzez wyłączenie przycisku w górnej części StartButton_Click programu obsługi zdarzeń.Następnie ponownie włączyć przycisk od wewnątrz finally zablokować po zakończeniu operacji, dzięki czemu użytkownicy mogą uruchamiać aplikację ponownie.

Poniższy kod przedstawia te zmiany, które są oznaczone gwiazdkami.Zmiany można dodać do kodu na końcu tego tematu lub możesz pobrać gotowy aplikacji z próbek asynchroniczne: współużytkowania wątkowości w aplikacji pulpitu .NET lub próbek asynchroniczne: współużytkowania wątkowości w aplikacji magazynu systemu Windows.Nazwa projektu jest DisableStartButton.

Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs)
    ' This line is commented out to make the results clearer in the output.
    'ResultsTextBox.Text = ""

    ' ***Disable the Start button until the downloads are complete. 
    StartButton.IsEnabled = False

    Try
        Await AccessTheWebAsync()

    Catch ex As Exception
        ResultsTextBox.Text &= vbCrLf & "Downloads failed."
    ' ***Enable the Start button in case you want to run the program again. 
    Finally
        StartButton.IsEnabled = True

    End Try
End Sub
private async void StartButton_Click(object sender, RoutedEventArgs e)
{
    // This line is commented out to make the results clearer in the output.
    //ResultsTextBox.Text = "";

    // ***Disable the Start button until the downloads are complete. 
    StartButton.IsEnabled = false; 

    try
    {
        await AccessTheWebAsync();
    }
    catch (Exception)
    {
        ResultsTextBox.Text += "\r\nDownloads failed.";
    }
    // ***Enable the Start button in case you want to run the program again. 
    finally
    {
        StartButton.IsEnabled = true;
    }
}

W wyniku zmian, przycisk przestaje odpowiadać podczas AccessTheWebAsync jest pobieranie witryn sieci Web, więc proces nie może ponownie wprowadzić.

JJ651641.collapse_all(pl-pl,VS.110).gifAnuluj i ponownie uruchomić operację

Zamiast wyłączać Start przycisk, możesz utrzymać przycisk aktywny, ale jeśli użytkownik wybierze ten przycisk ponownie, anulować operację, która jest już uruchomiony i najbardziej niedawno rozpoczęto kontynuowania operacji.

Aby uzyskać więcej informacji o unieważnieniu, zobacz Cienkiej Twoja aplikacja Async strojenia.

Aby skonfigurować ten scenariusz, należy wprowadzić następujące zmiany do podstawowego kodu, która jest dostępna w Przeglądanie i uruchamianie aplikacji przykładu.Możesz także pobrać gotowy aplikacji z próbek asynchroniczne: współużytkowania wątkowości w aplikacji pulpitu .NET lub próbek asynchroniczne: współużytkowania wątkowości w aplikacji magazynu systemu Windows.Nazwa tego projektu jest CancelAndRestart.

  1. Deklarujemy CancellationTokenSource zmiennej, cts, który znajduje się w zakresie dla wszystkich metod.

    Class MainWindow // Or Class MainPage
    
        ' *** Declare a System.Threading.CancellationTokenSource.
        Dim cts As CancellationTokenSource
    
    public partial class MainWindow : Window   // Or class MainPage
    {
        // *** Declare a System.Threading.CancellationTokenSource.
        CancellationTokenSource cts;
    
  2. W StartButton_Click, ustalić, czy operacja jest już w toku.Jeśli wartość cts ma wartość null (Nothing w języku Visual Basic), operacja nie jest już aktywna.Jeśli wartość nie jest null, operacja, która jest już uruchomiona został anulowany.

    ' *** If a download process is already underway, cancel it.
    If cts IsNot Nothing Then
        cts.Cancel()
    End If
    
    // *** If a download process is already underway, cancel it.
    if (cts != null)
    {
        cts.Cancel();
    }
    
  3. Ustaw cts na inną wartość, która reprezentuje bieżący proces.

    ' *** Now set cts to cancel the current process if the button is chosen again.
    Dim newCTS As CancellationTokenSource = New CancellationTokenSource()
    cts = newCTS
    
    // *** Now set cts to a new value that you can use to cancel the current process
    // if the button is chosen again.
    CancellationTokenSource newCTS = new CancellationTokenSource();
    cts = newCTS;
    
  4. Na koniec StartButton_Click, na bieżący proces się zakończy, więc należy ustawić wartość cts na null.

    ' *** When the process completes, signal that another process can proceed.
    If cts Is newCTS Then
        cts = Nothing
    End If
    
    // *** When the process is complete, signal that another process can begin.
    if (cts == newCTS)
        cts = null;
    

W poniższym kodzie pokazano wszystkie zmiany w StartButton_Click.Dodatki są oznaczone gwiazdkami.

Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs)

    ' This line is commented out to make the results clearer. 
    'ResultsTextBox.Text = ""


    ' *** If a download process is underway, cancel it.
    If cts IsNot Nothing Then
        cts.Cancel()
    End If

    ' *** Now set cts to cancel the current process if the button is chosen again.
    Dim newCTS As CancellationTokenSource = New CancellationTokenSource()
    cts = newCTS

    Try
        ' *** Send a token to carry the message if the operation is canceled.
        Await AccessTheWebAsync(cts.Token)
        

    Catch ex As OperationCanceledException
        ResultsTextBox.Text &= vbCrLf & "Download canceled." & vbCrLf

    Catch ex As Exception
        ResultsTextBox.Text &= vbCrLf & "Downloads failed."
    End Try

    ' *** When the process is complete, signal that another process can proceed.
    If cts Is newCTS Then
        cts = Nothing
    End If
End Sub
private async void StartButton_Click(object sender, RoutedEventArgs e)
{
    // This line is commented out to make the results clearer in the output.
    //ResultsTextBox.Clear();

    // *** If a download process is already underway, cancel it.
    if (cts != null)
    {
        cts.Cancel();
    }

    // *** Now set cts to cancel the current process if the button is chosen again.
    CancellationTokenSource newCTS = new CancellationTokenSource();
    cts = newCTS;

    try
    {
        // ***Send cts.Token to carry the message if there is a cancellation request.
        await AccessTheWebAsync(cts.Token);
        
    }
    // *** Catch cancellations separately.
    catch (OperationCanceledException)
    {
        ResultsTextBox.Text += "\r\nDownloads canceled.\r\n";
    }
    catch (Exception)
    {
        ResultsTextBox.Text += "\r\nDownloads failed.\r\n";
    }
    // *** When the process is complete, signal that another process can proceed.
    if (cts == newCTS)
        cts = null;
}

W AccessTheWebAsync, należy wprowadzić następujące zmiany.

  • Należy dodać parametr do akceptowania token odwołania z StartButton_Click.

  • Użycie GetAsync metody do pobierania witryn sieci Web, ponieważ GetAsync akceptuje CancellationToken argument.

  • Przed wywołaniem DisplayResults do wyświetlania wyników dla każdego pobranego serwisu WWW, sprawdź ct Aby zweryfikować, że bieżąca operacja nie zostało anulowane.

Poniższy kod przedstawia te zmiany, które są oznaczone gwiazdkami.

' *** Provide a parameter for the CancellationToken from StartButton_Click.
Private Async Function AccessTheWebAsync(ct As CancellationToken) As Task

    ' Declare an HttpClient object.
    Dim client = New HttpClient()

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

    Dim total = 0
    Dim position = 0

    For Each url In urlList
        ' *** Use the HttpClient.GetAsync method because it accepts a 
        ' cancellation token.
        Dim response As HttpResponseMessage = Await client.GetAsync(url, ct)

        ' *** Retrieve the website contents from the HttpResponseMessage.
        Dim urlContents As Byte() = Await response.Content.ReadAsByteArrayAsync()

        ' *** Check for cancellations before displaying information about the 
        ' latest site. 
        ct.ThrowIfCancellationRequested()

        position += 1
        DisplayResults(url, urlContents, position)

        ' 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:  " & total & vbCrLf)
End Function
// *** Provide a parameter for the CancellationToken from StartButton_Click.
async Task AccessTheWebAsync(CancellationToken ct)
{
    // Declare an HttpClient object.
    HttpClient client = new HttpClient();

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

    var total = 0;
    var position = 0;

    foreach (var url in urlList)
    {
        // *** Use the HttpClient.GetAsync method because it accepts a 
        // cancellation token.
        HttpResponseMessage response = await client.GetAsync(url, ct);

        // *** Retrieve the website contents from the HttpResponseMessage.
        byte[] urlContents = await response.Content.ReadAsByteArrayAsync();

        // *** Check for cancellations before displaying information about the 
        // latest site. 
        ct.ThrowIfCancellationRequested();

        DisplayResults(url, urlContents, ++position);

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

Jeśli wybierzesz Start kilka razy przycisk jest uruchomiona ta aplikacja powinna dawać wyniki, które przypominają następujące dane wyjściowe.

1. msdn.microsoft.com/en-us/library/hh191443.aspx                83732
2. msdn.microsoft.com/en-us/library/aa578028.aspx               205273
3. msdn.microsoft.com/en-us/library/jj155761.aspx                29019
4. msdn.microsoft.com/en-us/library/hh290140.aspx               122505
5. msdn.microsoft.com/en-us/library/hh524395.aspx                68959
6. msdn.microsoft.com/en-us/library/ms404677.aspx               197325
Download canceled.

1. msdn.microsoft.com/en-us/library/hh191443.aspx                83732
2. msdn.microsoft.com/en-us/library/aa578028.aspx               205273
3. msdn.microsoft.com/en-us/library/jj155761.aspx                29019
Download canceled.

1. msdn.microsoft.com/en-us/library/hh191443.aspx                83732
2. msdn.microsoft.com/en-us/library/aa578028.aspx               205273
3. msdn.microsoft.com/en-us/library/jj155761.aspx                29019
4. msdn.microsoft.com/en-us/library/hh290140.aspx               117152
5. msdn.microsoft.com/en-us/library/hh524395.aspx                68959
6. msdn.microsoft.com/en-us/library/ms404677.aspx               197325
7. msdn.microsoft.com                                            42972
8. msdn.microsoft.com/en-us/library/ff730837.aspx               146159

TOTAL bytes returned:  890591

Aby wyeliminować częściowe listy, Usuń oznaczenie jako pierwszej linii kodu w StartButton_Click zaznaczenie tego pola tekstowego przy każdym ponownym uruchomieniu użytkownika operacji.

JJ651641.collapse_all(pl-pl,VS.110).gifUruchamianie wielu operacji i dane wyjściowe w kolejce

W tym przykładzie trzeciego jest najbardziej skomplikowanych, że aplikacja zaczyna się operacja asynchroniczna za każdym razem, gdy użytkownik zdecyduje się na Start przycisk, a wszystkie ukończenia wykonywania operacji.Pobrać żądanych operacji witryn sieci Web z listy asynchronicznie, ale sekwencyjnego przedstawiania danych wyjściowych z operacji.Oznacza to, rzeczywistego działania wczytywania danych jest z przeplotem, jako produkcja globalna w UZNAJĄC współużytkowania wątkowości pokazuje, ale na liście wyników dla każdej grupy jest prezentowane oddzielnie.

Operacje Podziel globalnym Task, pendingWork, który służy jako strażnika dla procesu wyświetlania.

Można uruchomić ten przykład wklejając zmiany w kodzie w Budowanie aplikacji, lub postępuj zgodnie z instrukcjami wyświetlanymi w Pobieranie aplikacji do pobierania go, a następnie uruchomić projekt QueueResults.

Następujące dane wyjściowe pokazuje wynik, jeśli użytkownik zdecyduje się na Start przycisk tylko raz.Etykieta literę A, wskazuje, że wynik jest po raz pierwszy Start wciśnięty jest przycisk.Liczby reprezentują kolejność adresów URL na liście elementów docelowych pobierania.

#Starting group A.
#Task assigned for group A.

A-1. msdn.microsoft.com/en-us/library/hh191443.aspx                87389
A-2. msdn.microsoft.com/en-us/library/aa578028.aspx               209858
A-3. msdn.microsoft.com/en-us/library/jj155761.aspx                30870
A-4. msdn.microsoft.com/en-us/library/hh290140.aspx               119027
A-5. msdn.microsoft.com/en-us/library/hh524395.aspx                71260
A-6. msdn.microsoft.com/en-us/library/ms404677.aspx               199186
A-7. msdn.microsoft.com                                            53266
A-8. msdn.microsoft.com/en-us/library/ff730837.aspx               148020

TOTAL bytes returned:  918876


#Group A is complete.

Jeśli użytkownik zdecyduje się na Start przycisk trzy razy, aplikacja generuje dane wyjściowe, podobne do następujących wierszy.Linie informacyjne, które rozpoczynają się od Funt znak (#) śledzenia postępu aplikacji.

#Starting group A.
#Task assigned for group A.

A-1. msdn.microsoft.com/en-us/library/hh191443.aspx                87389
A-2. msdn.microsoft.com/en-us/library/aa578028.aspx               207089
A-3. msdn.microsoft.com/en-us/library/jj155761.aspx                30870
A-4. msdn.microsoft.com/en-us/library/hh290140.aspx               119027
A-5. msdn.microsoft.com/en-us/library/hh524395.aspx                71259
A-6. msdn.microsoft.com/en-us/library/ms404677.aspx               199185

#Starting group B.
#Task assigned for group B.

A-7. msdn.microsoft.com                                            53266

#Starting group C.
#Task assigned for group C.

A-8. msdn.microsoft.com/en-us/library/ff730837.aspx               148010

TOTAL bytes returned:  916095

B-1. msdn.microsoft.com/en-us/library/hh191443.aspx                87389
B-2. msdn.microsoft.com/en-us/library/aa578028.aspx               207089
B-3. msdn.microsoft.com/en-us/library/jj155761.aspx                30870
B-4. msdn.microsoft.com/en-us/library/hh290140.aspx               119027
B-5. msdn.microsoft.com/en-us/library/hh524395.aspx                71260
B-6. msdn.microsoft.com/en-us/library/ms404677.aspx               199186

#Group A is complete.

B-7. msdn.microsoft.com                                            53266
B-8. msdn.microsoft.com/en-us/library/ff730837.aspx               148010

TOTAL bytes returned:  916097

C-1. msdn.microsoft.com/en-us/library/hh191443.aspx                87389
C-2. msdn.microsoft.com/en-us/library/aa578028.aspx               207089

#Group B is complete.

C-3. msdn.microsoft.com/en-us/library/jj155761.aspx                30870
C-4. msdn.microsoft.com/en-us/library/hh290140.aspx               119027
C-5. msdn.microsoft.com/en-us/library/hh524395.aspx                72765
C-6. msdn.microsoft.com/en-us/library/ms404677.aspx               199186
C-7. msdn.microsoft.com                                            56190
C-8. msdn.microsoft.com/en-us/library/ff730837.aspx               148010

TOTAL bytes returned:  920526

#Group C is complete.

Grupy B i C uruchomione przed grupy A został zakończony, ale dane wyjściowe dla każdej grupy są wyświetlane osobno.Wszystkie dane wyjściowe dla grupy A jako pierwsze, a następnie wszystkie dane wyjściowe dla grupy B, a następnie wszystkie dane wyjściowe dla grupy C.Aplikacja zawsze wyświetla grupy w kolejności i, dla każdej grupy zawsze wyświetla informacje o poszczególnych witryn sieci Web w kolejności, w jakiej adresy URL są wyświetlane na liście adresów URL.

Jednak nie można przewidzieć kolejność, w którym faktycznie stało się pliki do pobrania.Po uruchomieniu wielu grup zadań pobierania, które generują są wszystkie aktywne.Nie można zakładać, że A-1 zostanie pobrana przed B-1 i nie można zakładać, że A-1 będą pobierane przed A-2.

JJ651641.collapse_all(pl-pl,VS.110).gifDefinicje globalne

Przykładowy kod zawiera poniższe dwie deklaracje globalnego jest widoczna z wszystkich metod.

Class MainWindow    ' Class MainPage in Windows Store app.

    ' ***Declare the following variables where all methods can access them. 
    Private pendingWork As Task = Nothing
    Private group As Char = ChrW(AscW("A") - 1)
public partial class MainWindow : Window  // Class MainPage in Windows Store app.
{
    // ***Declare the following variables where all methods can access them. 
    private Task pendingWork = null;   
    private char group = (char)('A' - 1);

Task Zmiennej, pendingWork, nadzoruje proces wyświetlania i uniemożliwia dowolnej grupie przerwanie operacji wyświetlania innej grupy.Zmienna znaku group, etykiety danych wyjściowych z różnych grup, aby zweryfikować, że wyniki są wyświetlane w oczekiwanej kolejności.

JJ651641.collapse_all(pl-pl,VS.110).gifProcedura obsługi kliknięcia

Program obsługi zdarzeń StartButton_Click, rośnie list grupy za każdym razem, użytkownik zdecyduje się na Start przycisk.A następnie wywołań obsługi AccessTheWebAsync do uruchamiania operacji pobierania.

Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs)
    ' ***Verify that each group's results are displayed together, and that
    ' the groups display in order, by marking each group with a letter.
    group = ChrW(AscW(group) + 1)
    ResultsTextBox.Text &= String.Format(vbCrLf & vbCrLf & "#Starting group {0}.", group)

    Try
        ' *** Pass the group value to AccessTheWebAsync.
        Dim finishedGroup As Char = Await AccessTheWebAsync(group)

        ' The following line verifies a successful return from the download and 
        ' display procedures. 
        ResultsTextBox.Text &= String.Format(vbCrLf & vbCrLf & "#Group {0} is complete." & vbCrLf, finishedGroup)

    Catch ex As Exception
        ResultsTextBox.Text &= vbCrLf & "Downloads failed."

    End Try
End Sub
private async void StartButton_Click(object sender, RoutedEventArgs e)
{
    // ***Verify that each group's results are displayed together, and that
    // the groups display in order, by marking each group with a letter.
    group = (char)(group + 1);
    ResultsTextBox.Text += string.Format("\r\n\r\n#Starting group {0}.", group);

    try
    {
        // *** Pass the group value to AccessTheWebAsync.
        char finishedGroup = await AccessTheWebAsync(group);

        // The following line verifies a successful return from the download and
        // display procedures. 
        ResultsTextBox.Text += string.Format("\r\n\r\n#Group {0} is complete.\r\n", finishedGroup);
    }
    catch (Exception)
    {
        ResultsTextBox.Text += "\r\nDownloads failed.";
    }
}

JJ651641.collapse_all(pl-pl,VS.110).gifMetoda AccessTheWebAsync

W tym przykładzie dzieli AccessTheWebAsync do dwóch metod.Pierwsza metoda, AccessTheWebAsync, uruchamia wszystkie zadania pobierania dla grupy i wydzielane są pendingWork Aby kontrolować proces wyświetlania.Metoda wykorzystuje Language Integrated Query (LINQ kwerendy) i ToArray<TSource> do uruchomienia wszystkich zadań pobierania w tym samym czasie.

AccessTheWebAsyncnastępnie wywołuje FinishOneGroupAsync czekają na zakończenie każdego z plików i wyświetlanie jego długość.

FinishOneGroupAsyncZwraca przypisanego do zadania pendingWork w AccessTheWebAsync.Że wartość zapobiega przerwania przez inną operację przed zakończeniem zadania.

Private Async Function AccessTheWebAsync(grp As Char) As Task(Of Char)

    Dim client = New HttpClient()

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

    ' ***Kick off the downloads. The application of ToArray activates all the download tasks.
    Dim getContentTasks As Task(Of Byte())() =
        urlList.Select(Function(addr) client.GetByteArrayAsync(addr)).ToArray()

    ' ***Call the method that awaits the downloads and displays the results.
    ' Assign the Task that FinishOneGroupAsync returns to the gatekeeper task, pendingWork.
    pendingWork = FinishOneGroupAsync(urlList, getContentTasks, grp)

    ResultsTextBox.Text &=
        String.Format(vbCrLf & "#Task assigned for group {0}. Download tasks are active." & vbCrLf, grp)

    ' ***This task is complete when a group has finished downloading and displaying.
    Await pendingWork

    ' You can do other work here or just return.
    Return grp
End Function
private async Task<char> AccessTheWebAsync(char grp)
{
    HttpClient client = new HttpClient();

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

    // ***Kick off the downloads. The application of ToArray activates all the download tasks.
    Task<byte[]>[] getContentTasks = urlList.Select(url => client.GetByteArrayAsync(url)).ToArray();

    // ***Call the method that awaits the downloads and displays the results.
    // Assign the Task that FinishOneGroupAsync returns to the gatekeeper task, pendingWork.
    pendingWork = FinishOneGroupAsync(urlList, getContentTasks, grp);

    ResultsTextBox.Text += string.Format("\r\n#Task assigned for group {0}. Download tasks are active.\r\n", grp);

    // ***This task is complete when a group has finished downloading and displaying.
    await pendingWork;

    // You can do other work here or just return.
    return grp;
}

JJ651641.collapse_all(pl-pl,VS.110).gifMetoda FinishOneGroupAsync

Ta metoda cykle przez zadań pobierania w grupie, oczekujące na każdy z nich, wyświetlaniem długość pobrany witryny sieci Web i dodanie do łącznej długości.

Pierwsza instrukcja w FinishOneGroupAsync korzysta z pendingWork aby upewnić się, że wprowadzenie metody nie koliduje z operację, która jest już w trakcie wyświetlania lub już oczekuje.Jeśli takie działanie jest w toku, wprowadzając operacji oczekiwania kolei.

Private Async Function FinishOneGroupAsync(urls As List(Of String), contentTasks As Task(Of Byte())(), grp As Char) As Task

    ' Wait for the previous group to finish displaying results.
    If pendingWork IsNot Nothing Then
        Await pendingWork
    End If

    Dim total = 0

    ' contentTasks is the array of Tasks that was created in AccessTheWebAsync.
    For i As Integer = 0 To contentTasks.Length - 1
        ' Await the download of a particular URL, and then display the URL and
        ' its length.
        Dim content As Byte() = Await contentTasks(i)
        DisplayResults(urls(i), content, i, grp)
        total += content.Length
    Next

    ' Display the total count for all of the websites.
    ResultsTextBox.Text &=
        String.Format(vbCrLf & vbCrLf & "TOTAL bytes returned:  " & total & vbCrLf)
End Function
private async Task FinishOneGroupAsync(List<string> urls, Task<byte[]>[] contentTasks, char grp)
{
    // ***Wait for the previous group to finish displaying results.
    if (pendingWork != null) await pendingWork;

    int total = 0;

    // contentTasks is the array of Tasks that was created in AccessTheWebAsync.
    for (int i = 0; i < contentTasks.Length; i++)
    {
        // Await the download of a particular URL, and then display the URL and
        // its length.
        byte[] content = await contentTasks[i];
        DisplayResults(urls[i], content, i, grp);
        total += content.Length;
    }

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

Można uruchomić ten przykład wklejając zmiany w kodzie w Budowanie aplikacji, lub postępuj zgodnie z instrukcjami wyświetlanymi w Pobieranie aplikacji do pobierania go, a następnie uruchom projekt QueueResults.

JJ651641.collapse_all(pl-pl,VS.110).gifPunkty orientacyjne

Linie informacyjne, które rozpoczynają się od znaku krzyżyka (#) w danych wyjściowych wyjaśnienia, jak działa w tym przykładzie.

Dane wyjściowe pokazuje następujące wzorce.

  • Grupy mogą być uruchamiane podczas poprzedniej grupy wyświetla dane wyjściowe, ale nie jest przerywana sposobu wyświetlania danych wyjściowych poprzednią grupę.

    #Starting group A.
    #Task assigned for group A. Download tasks are active.
    
    A-1. msdn.microsoft.com/en-us/library/hh191443.aspx                87389
    A-2. msdn.microsoft.com/en-us/library/aa578028.aspx               207089
    A-3. msdn.microsoft.com/en-us/library/jj155761.aspx                30870
    A-4. msdn.microsoft.com/en-us/library/hh290140.aspx               119037
    A-5. msdn.microsoft.com/en-us/library/hh524395.aspx                71260
    
    #Starting group B.
    #Task assigned for group B. Download tasks are active.
    
    A-6. msdn.microsoft.com/en-us/library/ms404677.aspx               199186
    A-7. msdn.microsoft.com                                            53078
    A-8. msdn.microsoft.com/en-us/library/ff730837.aspx               148010
    
    TOTAL bytes returned:  915919
    
    B-1. msdn.microsoft.com/en-us/library/hh191443.aspx                87388
    B-2. msdn.microsoft.com/en-us/library/aa578028.aspx               207089
    B-3. msdn.microsoft.com/en-us/library/jj155761.aspx                30870
    
    #Group A is complete.
    
    B-4. msdn.microsoft.com/en-us/library/hh290140.aspx               119027
    B-5. msdn.microsoft.com/en-us/library/hh524395.aspx                71260
    B-6. msdn.microsoft.com/en-us/library/ms404677.aspx               199186
    B-7. msdn.microsoft.com                                            53078
    B-8. msdn.microsoft.com/en-us/library/ff730837.aspx               148010
    
    TOTAL bytes returned:  915908
    
  • pendingWork Zadania ma wartość null (Nothing w języku Visual Basic) na początku FinishOneGroupAsync tylko w odniesieniu do grupy A, które uruchamiane jako pierwsze.Grupa A nie został jeszcze zakończony wyrażenie oczekiwać po dotarciu FinishOneGroupAsync.W związku z tym, sterowanie nie zwracane do AccessTheWebAsync, a pierwsze zadanie, aby pendingWork nie wystąpił.

  • Następujące dwa wiersze zawsze pojawiają się razem w danych wyjściowych.Ten kod nigdy nie zostanie przerwane między rozpoczęciem operacji grupy StartButton_Click i przypisywanie zadań dla grupy w celu pendingWork.

    #Starting group B.
    #Task assigned for group B. Download tasks are active.
    

    Po wejściu grupy StartButton_Click, operacja nie wykona operacji wyrażenie oczekiwać do czasu wejścia operacji FinishOneGroupAsync.W związku z tym nie inne działania przejąć kontrolę podczas tego segmentu kodu.

Przeglądanie i uruchamianie aplikacji przykładu

Aby lepiej zrozumieć app przykład, można go pobrać, ją wykonać samodzielnie lub przejrzeć kod na końcu tego tematu bez wprowadzania w aplikacji.

[!UWAGA]

Aby uruchomić przykład jako aplikacji pulpitu Windows Presentation Foundation (WPF), musisz mieć program Visual Studio 2012 r., programu Visual Studio Express 2012 dla pulpitu systemu Windows, lub 4.5.NET Framework zainstalowana na komputerze.

Aby uruchomić przykład jako Windows Store aplikacji, musisz mieć 8 Windows zainstalowany na komputerze.Ponadto, jeśli chcesz uruchomić przykład z programu Visual Studio, trzeba mieć również Visual Studio 2012 lub programu Visual Studio Express 2012 dla Windows 8 zainstalowane.Program Visual Studio 2010 nie można załadować projektów, które są przeznaczone do 4.5.NET Framework.

JJ651641.collapse_all(pl-pl,VS.110).gifPobieranie aplikacji

  1. Pobierz skompresowany plik z próbek asynchroniczne: współużytkowania wątkowości w aplikacji pulpitu .NET lub próbek asynchroniczne: współużytkowania wątkowości w aplikacji magazynu systemu Windows.

  2. Zdekompresuj plik, który został pobrany, a następnie uruchom program Visual Studio.

  3. Na pasku menu wybierz kolejno opcje Plik, Otwórz i Projekt/rozwiązanie.

  4. Przejdź do folderu, który przechowuje zdekompresowanych przykładowy kod, a następnie otwórz plik rozwiązania (.sln).

  5. W Solution Explorer, otwórz menu skrótów dla projektu, który chcesz uruchomić, a następnie wybierz jako StartUpProject.

  6. Wybierz klawisze CTRL + F5, aby skompilować i uruchomić projekt.

JJ651641.collapse_all(pl-pl,VS.110).gifBudowanie aplikacji

W poniższych sekcjach przedstawiono kod, aby zbudować w przykładzie, jako aplikacji WPF, lub jako Windows Store aplikacji.

Tworzenie aplikacji WPF

  1. Uruchom program Visual Studio 2012.

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

    Zostanie otwarte okno dialogowe Nowy projekt.

  3. W Szablonów okienku rozwiń węzeł programu Visual Basic lub Visual C#, a następnie rozwiń węzeł systemu Windows.

  4. Na liście typów projektów, wybierz polecenie Aplikacji WPF.

  5. Nazwa projektu WebsiteDownloadWPF, a następnie wybierz polecenie OK przycisk.

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

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

    Jeśli karta należy otworzyć menu skrótów dla MainWindow.xaml w Solution Explorer, a następnie wybierz polecenie View Code.

  7. W XAML widok na MainWindow.xaml, kod ten należy zastąpić następujący kod.

    <Window x:Class="MainWindow"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:WebsiteDownloadWPF"
        xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Width="517" Height="360">
            <Button x:Name="StartButton" Content="Start" HorizontalAlignment="Left" Margin="-1,0,0,0" VerticalAlignment="Top" Click="StartButton_Click" Height="53" Background="#FFA89B9B" FontSize="36" Width="518"  />
            <TextBox x:Name="ResultsTextBox" HorizontalAlignment="Left" Margin="-1,53,0,-36" TextWrapping="Wrap" VerticalAlignment="Top" Height="343" FontSize="10" ScrollViewer.VerticalScrollBarVisibility="Visible" Width="518" FontFamily="Lucida Console" />
        </Grid>
    </Window>
    
    <Window x:Class="WebsiteDownloadWPF.MainWindow"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:WebsiteDownloadWPF"
        xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Width="517" Height="360">
            <Button x:Name="StartButton" Content="Start" HorizontalAlignment="Left" Margin="-1,0,0,0" VerticalAlignment="Top" Click="StartButton_Click" Height="53" Background="#FFA89B9B" FontSize="36" Width="518"  />
            <TextBox x:Name="ResultsTextBox" HorizontalAlignment="Left" Margin="-1,53,0,-36" TextWrapping="Wrap" VerticalAlignment="Top" Height="343" FontSize="10" ScrollViewer.VerticalScrollBarVisibility="Visible" Width="518" FontFamily="Lucida Console" />
        </Grid>
    </Window>
    

    Proste okno zawierające pola tekstowego i przycisku pojawia się w Projekt widok MainWindow.xaml.

  8. Dodaj odwołanie do System.Net.Http.

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

  10. W MainWindow.xaml.vb lub MainWindow.xaml.cs kod ten należy zastąpić następujący kod.

    ' Add the following Imports statements, and add a reference for System.Net.Http.
    Imports System.Net.Http
    Imports System.Threading
    
    Class MainWindow
    
        Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs)
            ' This line is commented out to make the results clearer in the output.
            'ResultsTextBox.Text = ""
    
            Try
                Await AccessTheWebAsync()
    
            Catch ex As Exception
                ResultsTextBox.Text &= vbCrLf & "Downloads failed."
    
            End Try
        End Sub
    
    
        Private Async Function AccessTheWebAsync() As Task
    
            ' Declare an HttpClient object.
            Dim client = New HttpClient()
    
            ' Make a list of web addresses.
            Dim urlList As List(Of String) = SetUpURLList()
    
            Dim total = 0
            Dim position = 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)
    
                position += 1
                DisplayResults(url, urlContents, position)
    
                ' 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:  " & total & vbCrLf)
        End Function
    
    
        Private Function SetUpURLList() As List(Of String)
            Dim urls = New List(Of String) From
            {
                "https://msdn.microsoft.com/en-us/library/hh191443.aspx",
                "https://msdn.microsoft.com/en-us/library/aa578028.aspx",
                "https://msdn.microsoft.com/en-us/library/jj155761.aspx",
                "https://msdn.microsoft.com/en-us/library/hh290140.aspx",
                "https://msdn.microsoft.com/en-us/library/hh524395.aspx",
                "https://msdn.microsoft.com/en-us/library/ms404677.aspx",
                "https://msdn.microsoft.com",
                "https://msdn.microsoft.com/en-us/library/ff730837.aspx"
            }
            Return urls
        End Function
    
    
        Private Sub DisplayResults(url As String, content As Byte(), pos As Integer)
            ' 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.
    
            ' Strip off the "http:'".
            Dim displayURL = url.Replace("http://", "")
            ' Display position in the URL list, the URL, and the number of bytes.
            ResultsTextBox.Text &= String.Format(vbCrLf & "{0}. {1,-58} {2,8}", pos, displayURL, content.Length)
        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.Threading;
    
    namespace WebsiteDownloadWPF
    {
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
    
            private async void StartButton_Click(object sender, RoutedEventArgs e)
            {
                // This line is commented out to make the results clearer in the output.
                //ResultsTextBox.Text = "";
    
                try
                {
                    await AccessTheWebAsync();
                }
                catch (Exception)
                {
                    ResultsTextBox.Text += "\r\nDownloads failed.";
                }
            }
    
    
            private async Task AccessTheWebAsync()
            {
                // Declare an HttpClient object.
                HttpClient client = new HttpClient();
    
                // Make a list of web addresses.
                List<string> urlList = SetUpURLList();
    
                var total = 0;
                var position = 0;
    
                foreach (var url in urlList)
                {
                    // GetByteArrayAsync returns a task. At completion, the task
                    // produces a byte array.
                    byte[] urlContents = await client.GetByteArrayAsync(url);
    
                    DisplayResults(url, urlContents, ++position);
    
                    // 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/en-us/library/hh191443.aspx",
                    "https://msdn.microsoft.com/en-us/library/aa578028.aspx",
                    "https://msdn.microsoft.com/en-us/library/jj155761.aspx",
                    "https://msdn.microsoft.com/en-us/library/hh290140.aspx",
                    "https://msdn.microsoft.com/en-us/library/hh524395.aspx",
                    "https://msdn.microsoft.com/en-us/library/ms404677.aspx",
                    "https://msdn.microsoft.com",
                    "https://msdn.microsoft.com/en-us/library/ff730837.aspx"
                };
                return urls;
            }
    
    
            private void DisplayResults(string url, byte[] content, int pos)
            {
                // 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.
    
                // Strip off the "http://".
                var displayURL = url.Replace("http://", "");
                // Display position in the URL list, the URL, and the number of bytes.
                ResultsTextBox.Text += string.Format("\n{0}. {1,-58} {2,8}", pos, displayURL, content.Length);
            }
        }
    }
    
  11. Wybierz polecenie klawisze CTRL + F5, aby uruchomić program, a następnie wybierz Start przycisk kilka razy.

  12. Wprowadź odpowiednie zmiany z Wyłącz przycisk Start, Anuluj i ponownie uruchomić operację, lub Uruchamianie wielu operacji i dane wyjściowe w kolejce do obsługi współużytkowania wątkowości.

Do budowania aplikacji magazynu systemu Windows

  1. Uruchom program Visual Studio 2012.

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

    Zostanie otwarte okno dialogowe Nowy projekt.

  3. W Installed, Szablony kategorii, rozwiń węzeł programu Visual Basic lub Visual C#, a następnie rozwiń węzeł Magazynu systemu Windows.

  4. Na liście typów projektów, wybierz polecenie App puste (XAML).

  5. Nazwa projektu WebsiteDownloadWin, a następnie wybierz polecenie OK przycisk.

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

  6. W Solution Explorer, otwórz menu skrótów dla MainPage.xaml, a następnie wybierz Otwórz.

  7. W XAML okno MainPage.xaml, kod ten zastąpić następujący kod.

    <Page
        x:Class="WebsiteDownloadWin.MainPage"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:WebsiteDownloadWin"
        xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d" FontSize="12">
    
        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <Button x:Name="StartButton" Content="Start" HorizontalAlignment="Left" Margin="325,77,0,0" VerticalAlignment="Top" Click="StartButton_Click" Height="145" Background="#FFA89B9B" FontSize="36" Width="711"  />
            <TextBox x:Name="ResultsTextBox" HorizontalAlignment="Left" Margin="325,222,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Height="546" FontSize="10" ScrollViewer.VerticalScrollBarVisibility="Visible" Width="711" FontFamily="Lucida Console" />
        </Grid>
    </Page>
    

    Proste okno zawierające pola tekstowego i Start przycisk pojawia się w Projekt okno MainPage.xaml.

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

  9. Zastąp kod w MainPage.xaml.vb lub MainPage.xaml.cs z następującego kodu.

    ' Add the following Imports statements.
    Imports System.Threading.Tasks
    Imports System.Threading
    Imports System.Net.Http
    
    Public NotInheritable Class MainPage
        Inherits Page
    
        Protected Overrides Sub OnNavigatedTo(e As Navigation.NavigationEventArgs)
        End Sub
    
    
        Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs)
            ' This line is commented out to make the results clearer in the output.
            'ResultsTextBox.Text = ""
    
            Try
                Await AccessTheWebAsync()
    
            Catch ex As Exception
                ResultsTextBox.Text &= vbCrLf & "Downloads failed."
    
            End Try
        End Sub
    
    
        Private Async Function AccessTheWebAsync() As Task
    
            ' Declare an HttpClient object.
            Dim client = New HttpClient()
    
            ' Make a list of web addresses.
            Dim urlList As List(Of String) = SetUpURLList()
    
            Dim total = 0
            Dim position = 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)
    
                position += 1
                DisplayResults(url, urlContents, position)
    
                ' 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:  " & total & vbCrLf)
        End Function
    
    
        Private Function SetUpURLList() As List(Of String)
            Dim urls = New List(Of String) From
            {
                "https://msdn.microsoft.com/en-us/library/hh191443.aspx",
                "https://msdn.microsoft.com/en-us/library/aa578028.aspx",
                "https://msdn.microsoft.com/en-us/library/jj155761.aspx",
                "https://msdn.microsoft.com/en-us/library/hh290140.aspx",
                "https://msdn.microsoft.com/en-us/library/hh524395.aspx",
                "https://msdn.microsoft.com/en-us/library/ms404677.aspx",
                "https://msdn.microsoft.com",
                "https://msdn.microsoft.com/en-us/library/ff730837.aspx"
            }
            Return urls
        End Function
    
    
        Private Sub DisplayResults(url As String, content As Byte(), pos As Integer)
            ' 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.
    
            ' Strip off the "http:'".
            Dim displayURL = url.Replace("http://", "")
            ' Display position in the URL list, the URL, and the number of bytes.
            ResultsTextBox.Text &= String.Format(vbCrLf & "{0}. {1,-58} {2,8}", pos, displayURL, content.Length)
        End Sub
    End Class
    
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using Windows.Foundation;
    using Windows.Foundation.Collections;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Data;
    using Windows.UI.Xaml.Input;
    using Windows.UI.Xaml.Media;
    using Windows.UI.Xaml.Navigation;
    
    // Add the following using directives. 
    using System.Threading.Tasks;
    using System.Threading;
    using System.Net.Http;
    
    
    namespace WebsiteDownloadWin
    {
        public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
            }
    
            private async void StartButton_Click(object sender, RoutedEventArgs e)
            {
                // This line is commented out to make the results clearer in the output.
                //ResultsTextBox.Text = "";
    
                try
                {
                    await AccessTheWebAsync();
                }
                catch (Exception)
                {
                    ResultsTextBox.Text += "\r\nDownloads failed.";
                }
            }
    
    
            private async Task AccessTheWebAsync()
            {
                // Declare an HttpClient object.
                HttpClient client = new HttpClient();
    
                // Make a list of web addresses.
                List<string> urlList = SetUpURLList();
    
                var total = 0;
                var position = 0;
    
                foreach (var url in urlList)
                {
                    // GetByteArrayAsync returns a task. At completion, the task
                    // produces a byte array.
                    byte[] urlContents = await client.GetByteArrayAsync(url);
    
                    DisplayResults(url, urlContents, ++position);
    
                    // 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/en-us/library/hh191443.aspx",
                    "https://msdn.microsoft.com/en-us/library/aa578028.aspx",
                    "https://msdn.microsoft.com/en-us/library/jj155761.aspx",
                    "https://msdn.microsoft.com/en-us/library/hh290140.aspx",
                    "https://msdn.microsoft.com/en-us/library/hh524395.aspx",
                    "https://msdn.microsoft.com/en-us/library/ms404677.aspx",
                    "https://msdn.microsoft.com",
                    "https://msdn.microsoft.com/en-us/library/ff730837.aspx"
                };
                return urls;
            }
    
    
            private void DisplayResults(string url, byte[] content, int pos)
            {
                // 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.
    
                // Strip off the "http://".
                var displayURL = url.Replace("http://", "");
                // Display position in the URL list, the URL, and the number of bytes.
                ResultsTextBox.Text += string.Format("\n{0}. {1,-58} {2,8}", pos, displayURL, content.Length);
            }
        }
    }
    
  10. Wybierz polecenie klawisze CTRL + F5, aby uruchomić program, a następnie wybierz Start przycisk kilka razy.

  11. Wprowadź odpowiednie zmiany z Wyłącz przycisk Start, Anuluj i ponownie uruchomić operację, lub Uruchamianie wielu operacji i dane wyjściowe w kolejce do obsługi współużytkowania wątkowości.

Zobacz też

Zadania

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

Koncepcje

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

Inne zasoby

Programowanie asynchronicznego (Sklep Windows aplikacje)

Szybki Start: wywołanie asynchroniczne interfejsów API w języku C# lub Visual Basic