Sdílet prostřednictvím


Zpracování přeentrancy v asynchronních aplikacích (Visual Basic)

Když do aplikace zahrnete asynchronní kód, měli byste zvážit a případně zabránit opakovanému zadávání, což znamená opětovné zadání asynchronní operace před dokončením. Pokud neidentifikujete a nezpracujete možnosti opětovného zobrazení, může to způsobit neočekávané výsledky.

Poznámka:

Pokud chcete spustit příklad, musíte mít na počítači nainstalovanou sadu Visual Studio 2012 nebo novější a rozhraní .NET Framework 4.5 nebo novější.

Poznámka:

Protokol TLS (Transport Layer Security) verze 1.2 je teď minimální verzí, která se má použít ve vývoji vaší aplikace. Pokud vaše aplikace cílí na rozhraní .NET Framework starší než 4.7, projděte si následující článek osvědčených postupů pro protokol TLS (Transport Layer Security) s rozhraním .NET Framework.

Rozpoznávání opětovného vytváření

V příkladu v tomto tématu uživatelé vyberou tlačítko Start , aby zahájili asynchronní aplikaci, která stáhne řadu webů a vypočítá celkový počet bajtů, které se stáhnou. Synchronní verze příkladu by reagovala stejným způsobem bez ohledu na to, kolikrát uživatel toto tlačítko zvolí, protože po prvním spuštění vlákno uživatelského rozhraní tyto události ignoruje, dokud se aplikace nedokončí. V asynchronní aplikaci však vlákno uživatelského rozhraní nadále reaguje a před dokončením můžete asynchronní operaci zadat znovu.

Následující příklad ukazuje očekávaný výstup, pokud uživatel vybere tlačítko Start pouze jednou. Zobrazí se seznam stažených webů s velikostí jednotlivých webů v bajtech. Celkový počet bajtů se zobrazí na konci.

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

TOTAL bytes returned:  890591

Pokud však uživatel vybere tlačítko více než jednou, obslužná rutina události se opakovaně vyvolá a proces stahování se pokaždé znovu zadá. V důsledku toho je několik asynchronních operací spuštěných současně, výstup prokládání výsledků a celkový počet bajtů je matoucí.

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

TOTAL bytes returned:  890591

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

TOTAL bytes returned:  890591

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

TOTAL bytes returned:  890591

Kód, který vytvoří tento výstup, si můžete prohlédnout tak, že se posunete na konec tohoto tématu. S kódem můžete experimentovat stažením řešení do místního počítače a následným spuštěním projektu WebsiteDownload nebo pomocí kódu na konci tohoto tématu vytvořit vlastní projekt. Další informace a pokyny najdete v tématu Kontrola a spuštění ukázkové aplikace.

Zpracování přeentrování

V závislosti na tom, co má vaše aplikace dělat, můžete zpracovávat opakování různými způsoby. Toto téma obsahuje následující příklady:

Zakázat tlačítko Start

Tlačítko Start můžete zablokovat, když je operace spuštěná, zakázáním tlačítka v horní části obslužné rutiny StartButton_Click události. Jakmile se operace dokončí, můžete tlačítko Finally po dokončení operace znovu aktivovat, aby uživatelé mohli aplikaci spustit znovu.

Následující kód ukazuje tyto změny, které jsou označené hvězdičkami. Změny kódu můžete přidat na konec tohoto tématu nebo si můžete stáhnout dokončenou aplikaci z asynchronních ukázek: Opětovné zadání v desktopových aplikacích .NET. Název projektu je 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

V důsledku změn tlačítko během stahování webů nereaguje AccessTheWebAsync , takže proces se nedá znovu zadat.

Zrušení a restartování operace

Místo zakázání tlačítka Start můžete tlačítko zachovat aktivní, ale pokud uživatel toto tlačítko znovu zvolí, zrušte operaci, která už je spuštěná, a nechte operaci, která byla naposledy spuštěna, pokračovat.

Další informace o zrušení naleznete v tématu Jemné ladění asynchronní aplikace (Visual Basic).

Pokud chcete tento scénář nastavit, proveďte následující změny základního kódu, který je k dispozici v části Revize a Spuštění ukázkové aplikace. Dokončenou aplikaci si můžete stáhnout také z asynchronních ukázek: Opětovné zadání v desktopových aplikacích .NET. Název tohoto projektu je CancelAndRestart.

  1. Deklarujte proměnnou CancellationTokenSource , ctskterá je v oboru pro všechny metody.

    Class MainWindow // Or Class MainPage
    
        ' *** Declare a System.Threading.CancellationTokenSource.
        Dim cts As CancellationTokenSource
    
  2. Určete StartButton_Click, zda již probíhá operace. Pokud je Nothinghodnota cts , žádná operace již není aktivní. Pokud hodnota není Nothing, operace, která je již spuštěná, je zrušena.

    ' *** If a download process is already underway, cancel it.
    If cts IsNot Nothing Then
        cts.Cancel()
    End If
    
  3. Nastavte cts na jinou hodnotu, která představuje aktuální proces.

    ' *** Now set cts to cancel the current process if the button is chosen again.
    Dim newCTS As CancellationTokenSource = New CancellationTokenSource()
    cts = newCTS
    
  4. Na konci StartButton_Click, aktuální proces je dokončen, takže nastavte hodnotu cts zpět na Nothing.

    ' *** When the process completes, signal that another process can proceed.
    If cts Is newCTS Then
        cts = Nothing
    End If
    

Následující kód ukazuje všechny změny v StartButton_Click. Doplňky jsou označené hvězdičkami.

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

Proveďte AccessTheWebAsyncnásledující změny.

  • Přidejte parametr pro přijetí tokenu zrušení z StartButton_Click.

  • Tuto metodu GetAsync použijte ke stažení webů, protože GetAsync přijímá CancellationToken argument.

  • Než zavoláte DisplayResults , aby se zobrazily výsledky pro každý stažený web, zkontrolujte ct , jestli se aktuální operace nezrušila.

Následující kód ukazuje tyto změny, které jsou označené hvězdičkami.

' *** 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

Pokud během běhu této aplikace vyberete tlačítko Start několikrát, mělo by dojít k výsledkům, které se podobají následujícímu výstupu:

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

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

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

TOTAL bytes returned:  890591

Pokud chcete odstranit částečné seznamy, odkomentujte první řádek kódu StartButton_Click , aby se textové pole při každém restartování operace zrušilo.

Spuštění více operací a zařadí výstup do fronty

Tento třetí příklad je nejkomplikovanější v tom, že aplikace spustí další asynchronní operaci pokaždé, když uživatel zvolí tlačítko Start , a všechny operace se spustí do dokončení. Všechny požadované operace stahují weby ze seznamu asynchronně, ale výstup z operací se zobrazí postupně. To znamená, že skutečná aktivita stahování se proloží, protože výstup v části Rozpoznávání reentrancy ukazuje, ale seznam výsledků pro každou skupinu se zobrazí samostatně.

Operace sdílejí globální Task, pendingWorkkterý slouží jako vrátný pro proces zobrazení.

Tento příklad můžete spustit tak, že změny vložíte do kódu při sestavování aplikace, nebo podle pokynů v části Stažení aplikace stáhnete ukázku a pak spustíte projekt QueueResults.

Následující výstup ukazuje výsledek, pokud uživatel vybere tlačítko Start pouze jednou. Popisek písmene A označuje, že výsledek pochází od prvního výběru tlačítka Start . Čísla zobrazují pořadí adres URL v seznamu cílů stahování.

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

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

TOTAL bytes returned:  918876

#Group A is complete.

Pokud uživatel třikrát zvolí tlačítko Start , aplikace vytvoří výstup podobný následujícím řádkům. Informační čáry, které začínají znakem libry (#), sledují průběh aplikace.

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

A-1. msdn.microsoft.com/library/hh191443.aspx                87389
A-2. msdn.microsoft.com/library/aa578028.aspx               207089
A-3. msdn.microsoft.com/library/jj155761.aspx                30870
A-4. msdn.microsoft.com/library/hh290140.aspx               119027
A-5. msdn.microsoft.com/library/hh524395.aspx                71259
A-6. msdn.microsoft.com/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/library/ff730837.aspx               148010

TOTAL bytes returned:  916095

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

#Group A is complete.

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

TOTAL bytes returned:  916097

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

#Group B is complete.

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

TOTAL bytes returned:  920526

#Group C is complete.

Skupiny B a C začínají před dokončením skupiny A, ale výstup pro každou skupinu se zobrazí samostatně. Nejprve se zobrazí veškerý výstup pro skupinu A, následovaný veškerým výstupem pro skupinu B a následným výstupem pro skupinu C. Aplikace vždy zobrazí skupiny v pořadí a pro každou skupinu vždy zobrazí informace o jednotlivých webech v pořadí, v jakém se adresy URL zobrazují v seznamu adres URL.

Nemůžete ale předpovědět pořadí, ve kterém se stahování skutečně děje. Po spuštění několika skupin jsou úlohy stahování, které vygenerují, aktivní. Nemůžete předpokládat, že se A-1 stáhne před B-1 a nemůžete předpokládat, že se A-1 stáhne před A-2.

Globální definice

Vzorový kód obsahuje následující dvě globální deklarace, které jsou viditelné ze všech 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)

Proměnná TaskpendingWork, dohlíží na proces zobrazení a zabraňuje jakékoli skupině v přerušení operace zobrazení jiné skupiny. Proměnná znaku groupoznačuje výstup z různých skupin, aby se ověřilo, že výsledky se zobrazují v očekávaném pořadí.

Obslužná rutina události kliknutí

Obslužná rutina události zvýší písmeno skupiny pokaždé, StartButton_Clickkdyž uživatel zvolí tlačítko Start . Potom volání AccessTheWebAsync obslužné rutiny ke spuštění operace stahování.

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

Metoda AccessTheWebAsync

Tento příklad se rozdělí AccessTheWebAsync na dvě metody. První metoda , AccessTheWebAsyncspustí všechny úlohy stahování pro skupinu a nastaví pendingWork pro řízení procesu zobrazení. Metoda používá jazykový integrovaný dotaz (LINQ query) a ToArray ke spuštění všech úloh stahování najednou.

AccessTheWebAsync pak volání FinishOneGroupAsync , která čekají na dokončení každého stažení a zobrazí jeho délku.

FinishOneGroupAsyncvrátí úkol, ke pendingWork kterému je přiřazen .AccessTheWebAsync Tato hodnota zabraňuje přerušení jinou operací před dokončením úkolu.

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

Metoda FinishOneGroupAsync

Tato metoda prochází úkoly stahování ve skupině, čeká na každý z nich, zobrazí délku staženého webu a přidá celkovou délku.

První příkaz, který FinishOneGroupAsync se používá pendingWork k ověření, že zadávání metody nezasahuje do operace, která je již v procesu zobrazení nebo která již čeká. Pokud taková operace probíhá, musí operace zadávání počkat.

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

Tento příklad můžete spustit vložením změn do kódu při sestavování aplikace, nebo můžete postupovat podle pokynů v části Stažení aplikace a stáhnout ukázku a pak spustit projekt QueueResults.

Body zájmu

Informační čáry začínající znakem libry (#) ve výstupu vysvětlují, jak tento příklad funguje.

Výstup ukazuje následující vzory.

  • Skupinu je možné spustit, když předchozí skupina zobrazuje svůj výstup, ale zobrazení výstupu předchozí skupiny se nepřeruší.

    #Starting group A.
    #Task assigned for group A. Download tasks are active.
    
    A-1. msdn.microsoft.com/library/hh191443.aspx                87389
    A-2. msdn.microsoft.com/library/aa578028.aspx               207089
    A-3. msdn.microsoft.com/library/jj155761.aspx                30870
    A-4. msdn.microsoft.com/library/hh290140.aspx               119037
    A-5. msdn.microsoft.com/library/hh524395.aspx                71260
    
    #Starting group B.
    #Task assigned for group B. Download tasks are active.
    
    A-6. msdn.microsoft.com/library/ms404677.aspx               199186
    A-7. msdn.microsoft.com                                            53078
    A-8. msdn.microsoft.com/library/ff730837.aspx               148010
    
    TOTAL bytes returned:  915919
    
    B-1. msdn.microsoft.com/library/hh191443.aspx                87388
    B-2. msdn.microsoft.com/library/aa578028.aspx               207089
    B-3. msdn.microsoft.com/library/jj155761.aspx                30870
    
    #Group A is complete.
    
    B-4. msdn.microsoft.com/library/hh290140.aspx               119027
    B-5. msdn.microsoft.com/library/hh524395.aspx                71260
    B-6. msdn.microsoft.com/library/ms404677.aspx               199186
    B-7. msdn.microsoft.com                                            53078
    B-8. msdn.microsoft.com/library/ff730837.aspx               148010
    
    TOTAL bytes returned:  915908
    
  • Úkol pendingWork je Nothing na začátku FinishOneGroupAsync pouze pro skupinu A, která začala jako první. Skupina A ještě nedokončila výraz await, když dosáhne FinishOneGroupAsync. Proto se ovládací prvek nevrátil do AccessTheWebAsynca první přiřazení, ke pendingWork kterému nedošlo.

  • Následující dva řádky se ve výstupu vždy zobrazí společně. Kód se nikdy nepřeruší mezi spuštěním operace skupiny a StartButton_Click přiřazením úkolu ke skupině .pendingWork

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

    Po zadání StartButton_Clickskupiny operace nedokončí výraz await, dokud operace nezadá FinishOneGroupAsync. Proto žádná jiná operace nemůže získat kontrolu během tohoto segmentu kódu.

Kontrola a spuštění ukázkové aplikace

Pokud chcete lépe porozumět ukázkové aplikaci, můžete si ji stáhnout, sestavit sami nebo zkontrolovat kód na konci tohoto tématu bez implementace aplikace.

Poznámka:

Pokud chcete spustit příklad jako desktopovou aplikaci WPF (Windows Presentation Foundation), musíte mít na počítači nainstalovanou sadu Visual Studio 2012 nebo novější a rozhraní .NET Framework 4.5 nebo novější.

Stažení aplikace

  1. Stáhněte komprimovaný soubor z asynchronních ukázek: Opětovné zařazení do desktopových aplikací .NET.

  2. Dekomprimujte soubor, který jste stáhli, a spusťte Visual Studio.

  3. Na řádku nabídek zvolte Soubor, Otevřít, Projekt nebo Řešení.

  4. Přejděte do složky, která obsahuje dekompresovaný ukázkový kód, a otevřete soubor řešení (.sln).

  5. V Průzkumník řešení otevřete místní nabídku projektu, který chcete spustit, a pak zvolte Nastavit jako startUpProject.

  6. Vyberte klávesy CTRL+F5 pro sestavení a spuštění projektu.

Sestavení aplikace

Následující část obsahuje kód pro sestavení příkladu jako aplikace WPF.

Vytvoření aplikace WPF
  1. Spusťte Visual Studio.

  2. Na řádku nabídek zvolte Soubor, Nový, Projekt.

    Otevře se dialogové okno Nový projekt .

  3. V podokně Nainstalované šablony rozbalte Visual Basic a potom rozbalte Windows.

  4. V seznamu typů projektů zvolte aplikaci WPF.

  5. Pojmenujte projekt WebsiteDownloadWPF, zvolte verzi rozhraní .NET Framework verze 4.6 nebo vyšší a klikněte na tlačítko OK .

    Nový projekt se zobrazí v Průzkumník řešení.

  6. V editoru Visual Studio Code zvolte kartu MainWindow.xaml .

    Pokud karta není viditelná, otevřete místní nabídku pro MainWindow.xaml v Průzkumník řešení a pak zvolte Zobrazit kód.

  7. V zobrazení XAML MainWindow.xaml nahraďte kód následujícím kódem.

    <Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:WebsiteDownloadWPF"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://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>
    

    Jednoduché okno, které obsahuje textové pole a tlačítko se zobrazí v návrhovém zobrazení MainWindow.xaml.

  8. V Průzkumník řešení klikněte pravým tlačítkem myši na Odkazy a vyberte Přidat odkaz.

    Přidejte odkaz pro System.Net.Http, pokud ještě není vybraný.

  9. V Průzkumník řešení otevřete místní nabídku pro MainWindow.xaml.vb a pak zvolte Zobrazit kód.

  10. V MainWindow.xaml.vb nahraďte kód následujícím kódem.

    ' 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)
            System.Net.ServicePointManager.SecurityProtocol = System.Net.ServicePointManager.SecurityProtocol Or System.Net.SecurityProtocolType.Tls12
    
            ' 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/library/hh191443.aspx",
                "https://msdn.microsoft.com/library/aa578028.aspx",
                "https://msdn.microsoft.com/library/jj155761.aspx",
                "https://msdn.microsoft.com/library/hh290140.aspx",
                "https://msdn.microsoft.com/library/hh524395.aspx",
                "https://msdn.microsoft.com/library/ms404677.aspx",
                "https://msdn.microsoft.com",
                "https://msdn.microsoft.com/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("https://", "")
            ' 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
    
  11. Pokud chcete program spustit, zvolte klávesy CTRL+F5 a několikrát zvolte tlačítko Start .

  12. Proveďte změny v části Zakázat tlačítko Start, Zrušit a Restartovat operaci nebo Spustit více operací a zařazení výstupu do fronty pro zpracování přejmezení.

Viz také