Aracılığıyla paylaş


Denetim akışında zaman uyumsuz programlar (C# ve Visual Basic)

Yazma ve zaman uyumsuz programlar kullanarak daha kolay korumak Async ve Await anahtar sözcükler.Ancak, programın nasıl çalıştığını anlamıyorsanız sonuçları size sürpriz.Bu konuda denetim gider bir yönteminden başka ve hangi bilgileri her zaman aktarıldığı göstermek için basit bir zaman uyumsuz program aracılığıyla denetim akışını izler.

[!NOT]

Async Ve Await anahtar sözcükler Visual Studio 2012 tanıtılan.Bu sürümdeki yeni özellikler hakkında daha fazla bilgi için bkz: Visual Studio 2012'daki Yenilikler.

Genel olarak, zaman uyumsuz kod ile içeren yöntemleri işaretleyin Zaman uyumsuz (Visual Basic) veya zaman uyumsuz (C#) değiştirici.Kullanabileceğiniz bir zaman uyumsuz değiştiricisi ile işaretlenmiş bir yöntem bir (Visual Basic) Await veya bekler (C#) burada tamamlamak çağrılan zaman uyumsuz işlem için beklenecek yöntemi duraklatır belirlemek için işleç.Daha fazla bilgi için bkz. Zaman uyumsuz zaman uyumsuz programlama ve beklemek (C# ve Visual Basic).

Aşağıdaki örnek, bir dize olarak belirtilen bir Web sitesinin içeriği karşıdan yüklemek ve dizenin uzunluğu görüntülemek için zaman uyumsuz yöntemleri kullanır.Örneğin, aşağıdaki iki yöntem içerir.

  • startButton_Click, hangi çağrıları AccessTheWebAsync ve sonucu görüntüler.

  • AccessTheWebAsync, bir dize olarak bir Web sitesinin içeriği karşıdan yükler ve dize uzunluğunu döndürür.AccessTheWebAsynczaman uyumsuz bir kullanır HttpClient yöntemi, GetStringAsync(String), içeriği karşıdan yüklemek için.

Numaralı görüntü olarak işaretlenmiş her noktada ne olacağını açıklayan ve programın nasıl çalıştığını anlamanıza yardımcı olacak program boyunca stratejik noktalarda satırları görüntülenir."Bir"ile "altı." etiketli görüntü satırları Program bu kod satırları eriştiği sırada etiketleri temsil eder.

Aşağıdaki kod, program bir özetini gösterir.

Class MainWindow

    Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs) Handles StartButton.Click

        ' ONE
        Dim getLengthTask As Task(Of Integer) = AccessTheWebAsync()

        ' FOUR
        Dim contentLength As Integer = Await getLengthTask

        ' SIX
        ResultsTextBox.Text &=
            String.Format(vbCrLf & "Length of the downloaded string: {0}." & vbCrLf, contentLength)

    End Sub


    Async Function AccessTheWebAsync() As Task(Of Integer)

        ' TWO
        Dim client As HttpClient = New HttpClient() 
        Dim getStringTask As Task(Of String) = 
            client.GetStringAsync("https://msdn.microsoft.com")

        ' THREE
        Dim urlContents As String = Await getStringTask

        ' FIVE
        Return urlContents.Length
    End Function

End Class
public partial class MainWindow : Window
{
    // . . .
    private async void startButton_Click(object sender, RoutedEventArgs e)
    {
        // ONE
        Task<int> getLengthTask = AccessTheWebAsync();

        // FOUR
        int contentLength = await getLengthTask;

        // SIX
        resultsTextBox.Text +=
            String.Format("\r\nLength of the downloaded string: {0}.\r\n", contentLength);
    }


    async Task<int> AccessTheWebAsync()
    {
        // TWO
        HttpClient client = new HttpClient();
        Task<string> getStringTask =
            client.GetStringAsync("https://msdn.microsoft.com");

        // THREE                 
        string urlContents = await getStringTask;

        // FIVE
        return urlContents.Length;
    }
}

"Bir"ile "altı," etiketli yerleşimlerin her programın geçerli durumu hakkında bilgi görüntüler.Şu çıktı üretilir.

ONE:   Entering startButton_Click.
           Calling AccessTheWebAsync.

TWO:   Entering AccessTheWebAsync.
           Calling HttpClient.GetStringAsync.

THREE: Back in AccessTheWebAsync.
           Task getStringTask is started.
           About to await getStringTask & return a Task<int> to startButton_Click.

FOUR:  Back in startButton_Click.
           Task getLengthTask is started.
           About to await getLengthTask -- no caller to return to.

FIVE:  Back in AccessTheWebAsync.
           Task getStringTask is complete.
           Processing the return statement.
           Exiting from AccessTheWebAsync.

SIX:   Back in startButton_Click.
           Task getLengthTask is finished.
           Result from AccessTheWebAsync is stored in contentLength.
           About to display contentLength and exit.

Length of the downloaded string: 33946.

Program ayarlama

Bu konuda kullanan kod msdn sitesinden yükleyin veya, onu kendiniz oluşturabilirsiniz.

[!NOT]

Örneği çalıştırmak için Visual Studio 2012, Visual Studio 2012, Express veya .NET Framework 4.5 bilgisayarınızda yüklü olmalıdır.

Hh873191.collapse_all(tr-tr,VS.110).gifProgram yükleme

Uygulama için bu konudan indirebilirsiniz zaman uyumsuz örnek: akış denetimi zaman uyumsuz program.Aşağıdaki adımlar açın ve programı çalıştırın.

  1. Karşıdan yüklenen dosyayı unzip ve sonra Başlat Visual Studio 2012.

  2. Menü çubuğunda, Dosya, , Proje/Çözüm seçeneklerini belirleyin.

  3. Sıkıştırması örnek kodu içeren klasöre gidin, çözüm (.sln) dosyasını açın ve sonra F5 tuşuna basarak projeyi çalıştırın ve yapı seçin.

Hh873191.collapse_all(tr-tr,VS.110).gifProgram kendiniz yapılandırmak

Aşağıdaki kod örneğinde bu konu için aşağıdaki Windows Presentation Foundation (wpf) proje içerir.

Proje çalıştırmak için aşağıdaki adımları uygulayın:

  1. Visual &Studio'yu başlatın.

  2. Menü çubuğunda Dosya, Yeni, Proje'yi seçin.

    Yeni Proje iletişim kutusu açılır.

  3. İçinde Yüklü Şablonlar bölmesinde seçin Visual Basic veya **Visual C#**ve sonra seçin wpf uygulaması proje türleri listesinde.

  4. Girin AsyncTracer projenin adı ve sonra seçin Tamam düğmesi.

    Çözüm Gezgini'nde yeni proje görüntülenir.

  5. Visual Studio Kod Düzenleyicisi'nde seçin MainWindow.xaml sekme.

    Sekmesi görünür değilse, MainWindow.xaml içinde için kısayol menüsünü aç Çözüm Gezginive sonra seçin Görünüm kodu.

  6. İçinde xaml MainWindow.xaml görüntülemek, kodu aşağıdaki kod ile değiştirin.

    <Window
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="https://schemas.microsoft.com/expression/blend/2008" xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="MainWindow"
        Title="Control Flow Trace" Height="350" Width="525">
        <Grid>
            <Button x:Name="StartButton" Content="Start" HorizontalAlignment="Left" Margin="221,10,0,0" VerticalAlignment="Top" Width="75"/>
            <TextBox x:Name="ResultsTextBox" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Bottom" Width="510" Height="265" FontFamily="Lucida Console" FontSize="10" VerticalScrollBarVisibility="Visible" d:LayoutOverrides="HorizontalMargin"/>
    
        </Grid>
    </Window>
    
    <Window
            xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="https://schemas.microsoft.com/expression/blend/2008" xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="AsyncTracer.MainWindow"
            Title="Control Flow Trace" Height="350" Width="592">
        <Grid>
            <Button x:Name="startButton" Content="Start&#xa;" HorizontalAlignment="Left" Margin="250,10,0,0" VerticalAlignment="Top" Width="75" Height="24"  Click="startButton_Click" d:LayoutOverrides="GridBox"/>
            <TextBox x:Name="resultsTextBox" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Bottom" Width="576" Height="265" FontFamily="Lucida Console" FontSize="10" VerticalScrollBarVisibility="Visible" Grid.ColumnSpan="3"/>
        </Grid>
    </Window>
    

    Metin kutusu ve bir düğme içeren basit bir pencere görünür Tasarım görünümünü MainWindow.xaml.

  7. Başvuru için System.Net.Http.

  8. İçinde Çözüm Gezgini, MainWindow.xaml.vb veya MainWindow.xaml.cs için kısayol menüsünü açın ve sonra seçin Görünüm kodu.

  9. MainWindow.xaml.vb veya MainWindow.xaml.cs, kodu aşağıdaki kod ile değiştirin.

    ' Add an Imports statement and a reference for System.Net.Http.
    Imports System.Net.Http
    
    Class MainWindow
    
        Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs) Handles StartButton.Click
    
            ' The display lines in the example lead you through the control shifts.
            ResultsTextBox.Text &= "ONE:   Entering StartButton_Click." & vbCrLf &
                "           Calling AccessTheWebAsync." & vbCrLf
    
            Dim getLengthTask As Task(Of Integer) = AccessTheWebAsync()
    
            ResultsTextBox.Text &= vbCrLf & "FOUR:  Back in StartButton_Click." & vbCrLf &
                "           Task getLengthTask is started." & vbCrLf &
                "           About to await getLengthTask -- no caller to return to." & vbCrLf
    
            Dim contentLength As Integer = Await getLengthTask
    
            ResultsTextBox.Text &= vbCrLf & "SIX:   Back in StartButton_Click." & vbCrLf &
                "           Task getLengthTask is finished." & vbCrLf &
                "           Result from AccessTheWebAsync is stored in contentLength." & vbCrLf &
                "           About to display contentLength and exit." & vbCrLf
    
            ResultsTextBox.Text &=
                String.Format(vbCrLf & "Length of the downloaded string: {0}." & vbCrLf, contentLength)
        End Sub
    
    
        Async Function AccessTheWebAsync() As Task(Of Integer)
    
            ResultsTextBox.Text &= vbCrLf & "TWO:   Entering AccessTheWebAsync."
    
            ' Declare an HttpClient object.
            Dim client As HttpClient = New HttpClient()
    
            ResultsTextBox.Text &= vbCrLf & "           Calling HttpClient.GetStringAsync." & vbCrLf
    
            ' GetStringAsync returns a Task(Of String). 
            Dim getStringTask As Task(Of String) = client.GetStringAsync("https://msdn.microsoft.com")
    
            ResultsTextBox.Text &= vbCrLf & "THREE: Back in AccessTheWebAsync." & vbCrLf &
                "           Task getStringTask is started."
    
            ' AccessTheWebAsync can continue to work until getStringTask is awaited.
    
            ResultsTextBox.Text &=
                vbCrLf & "           About to await getStringTask & return a Task(Of Integer) to StartButton_Click." & vbCrLf
    
            ' Retrieve the website contents when task is complete.
            Dim urlContents As String = Await getStringTask
    
            ResultsTextBox.Text &= vbCrLf & "FIVE:  Back in AccessTheWebAsync." &
                vbCrLf & "           Task getStringTask is complete." &
                vbCrLf & "           Processing the return statement." &
                vbCrLf & "           Exiting from AccessTheWebAsync." & vbCrLf
    
            Return urlContents.Length
        End Function
    
    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 a using directive and a reference for System.Net.Http;
    using System.Net.Http;
    
    namespace AsyncTracer
    {
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private async void startButton_Click(object sender, RoutedEventArgs e)
            {
                // The display lines in the example lead you through the control shifts.
                resultsTextBox.Text += "ONE:   Entering startButton_Click.\r\n" +
                    "           Calling AccessTheWebAsync.\r\n";
    
                Task<int> getLengthTask = AccessTheWebAsync();
    
                resultsTextBox.Text += "\r\nFOUR:  Back in startButton_Click.\r\n" +
                    "           Task getLengthTask is started.\r\n" +
                    "           About to await getLengthTask -- no caller to return to.\r\n";
    
                int contentLength = await getLengthTask;
    
                resultsTextBox.Text += "\r\nSIX:   Back in startButton_Click.\r\n" +
                    "           Task getLengthTask is finished.\r\n" +
                    "           Result from AccessTheWebAsync is stored in contentLength.\r\n" +
                    "           About to display contentLength and exit.\r\n";
    
                resultsTextBox.Text +=
                    String.Format("\r\nLength of the downloaded string: {0}.\r\n", contentLength);
            }
    
    
            async Task<int> AccessTheWebAsync()
            {
                resultsTextBox.Text += "\r\nTWO:   Entering AccessTheWebAsync.";
    
                // Declare an HttpClient object.
                HttpClient client = new HttpClient();
    
                resultsTextBox.Text += "\r\n           Calling HttpClient.GetStringAsync.\r\n";
    
                // GetStringAsync returns a Task<string>. 
                Task<string> getStringTask = client.GetStringAsync("https://msdn.microsoft.com");
    
                resultsTextBox.Text += "\r\nTHREE: Back in AccessTheWebAsync.\r\n" +
                    "           Task getStringTask is started.";
    
                // AccessTheWebAsync can continue to work until getStringTask is awaited.
    
                resultsTextBox.Text +=
                    "\r\n           About to await getStringTask and return a Task<int> to startButton_Click.\r\n";
    
                // Retrieve the website contents when task is complete.
                string urlContents = await getStringTask;
    
                resultsTextBox.Text += "\r\nFIVE:  Back in AccessTheWebAsync." +
                    "\r\n           Task getStringTask is complete." +
                    "\r\n           Processing the return statement." +
                    "\r\n           Exiting from AccessTheWebAsync.\r\n";
    
                return urlContents.Length;
            }
        }
    }
    
  10. Seçim programını çalıştırın ve sonra seçmek için F5 tuşuna Start düğmesi.

    Aşağıdaki çıktıyı görüntülenmesi gerekir.

    ONE:   Entering startButton_Click.
               Calling AccessTheWebAsync.
    
    TWO:   Entering AccessTheWebAsync.
               Calling HttpClient.GetStringAsync.
    
    THREE: Back in AccessTheWebAsync.
               Task getStringTask is started.
               About to await getStringTask & return a Task<int> to startButton_Click.
    
    FOUR:  Back in startButton_Click.
               Task getLengthTask is started.
               About to await getLengthTask -- no caller to return to.
    
    FIVE:  Back in AccessTheWebAsync.
               Task getStringTask is complete.
               Processing the return statement.
               Exiting from AccessTheWebAsync.
    
    SIX:   Back in startButton_Click.
               Task getLengthTask is finished.
               Result from AccessTheWebAsync is stored in contentLength.
               About to display contentLength and exit.
    
    Length of the downloaded string: 33946.
    

İzleme programı

Hh873191.collapse_all(tr-tr,VS.110).gifBirinci ve ikinci adımları

İlk iki satır olarak yolu izleme startButton_Click çağrıları AccessTheWebAsync, ve AccessTheWebAsync zaman uyumsuz çağırır HttpClient yöntemi GetStringAsync(String).Aşağıdaki resimde yöntem yöntem çağrıları özetlenmektedir.

Birinci ve ikinci adımları

Dönüş türünü AccessTheWebAsync ve client.GetStringAsync olan Task<TResult>.İçin AccessTheWebAsync, TResult olan bir tamsayı.İçin GetStringAsync, TResult olan bir dize.Zaman uyumsuz yöntem dönüş türleri hakkında daha fazla bilgi için bkz: Zaman uyumsuz dönüş türleri (C# ve Visual Basic).

Bir görev döndüren zaman uyumsuz yöntem denetimi çağırana geri geçtiğinde görev örneği döndürür.Denetimi döndüren bir zaman uyumsuz yöntemden çağıranına olduğunda ya da bir Await veya await çağrılan yöntemin veya çağrılan yöntemin ne zaman sona operatör karşılaştı.Bu işlemin bir parçası "Üç"ile "altı" etiketli satır izleme.

Hh873191.collapse_all(tr-tr,VS.110).gifÜÇ adım

İçinde AccessTheWebAsync, zaman uyumsuz yöntem GetStringAsync(String) hedef Web sayfasının içeriğini karşıdan yüklemek için çağrılır.Denetim döner dan client.GetStringAsync için AccessTheWebAsync , client.GetStringAsync döndürür.

client.GetStringAsync Yöntemi, göreve atanan dizeyi döndürür getStringTask değişken AccessTheWebAsync.Örnek program aşağıdaki satırda çağrısı gösterir client.GetStringAsync ve atama.

Dim getStringTask As Task(Of String) = client.GetStringAsync("https://msdn.microsoft.com")
Task<string> getStringTask = client.GetStringAsync("https://msdn.microsoft.com");

Görevi, bir promise tarafından olarak düşünmek client.GetStringAsync sonunda gerçek bir dize oluşturmak için.Bu arada, AccessTheWebAsync taahhüt edilen dizeden bağımlı değildir yapmak için iş client.GetStringAsync, iş devam edebilirsiniz ancak client.GetStringAsync bekler.Örnekte, "Üç" etiketli, aşağıdaki satırlar çıktı, bağımsız iş yapmak için Fırsat temsil eder.

THREE: Back in AccessTheWebAsync.
           Task getStringTask is started.
           About to await getStringTask & return a Task<int> to startButton_Click.

Aşağıdaki ifade ediyor askıya AccessTheWebAsync , getStringTask beklediğin.

Dim urlContents As String = Await getStringTask
string urlContents = await getStringTask;

Aşağıdaki resim denetiminden akışını gösterir client.GetStringAsync için atama getStringTask oluşturulması ve getStringTask await işleç uygulamaya.

ÜÇ adım

Await ifade askıya AccessTheWebAsync kadar client.GetStringAsync döndürür.Bu arada, denetimi çağırana döndürür AccessTheWebAsync, startButton_Click.

[!NOT]

Genellikle, bir zaman uyumsuz yöntem çağrısına hemen bekler.Örneğin, aşağıdaki atamalar birini oluşturur ve sonra bekler, önceki kod değiştirme getStringTask:

  • Visual Basic:Dim urlContents As String = Await client.GetStringAsync("https://msdn.microsoft.com")

  • C#:string urlContents = await client.GetStringAsync("https://msdn.microsoft.com");

Bu konuda, await işleç programı aracılığıyla denetim akışı işaretleme çıktı satırını sığdırmak için daha sonra uygulanır.

Hh873191.collapse_all(tr-tr,VS.110).gifDÖRT adım

Bildirilen dönüş türü AccessTheWebAsync olan Task(Of Integer) Visual Basic ve Task<int> C# [NULL]'ta.Bu nedenle, ne zaman AccessTheWebAsync olan askıya alındı, bir görev için bir tamsayı döndürür startButton_Click.Döndürülen görev olmadığını anlamak getStringTask.Yeni bir görev askıya alınmış yönteminde yapılması ne kalır gösteren tamsayı döndürülen görevdir AccessTheWebAsync.Gelen bir promise görevdir AccessTheWebAsync görev tamamlandığında, bir tamsayı üretmek için.

Bu görev için aşağıdaki deyim atar getLengthTask değişkeni.

Dim getLengthTask As Task(Of Integer) = AccessTheWebAsync()
Task<int> getLengthTask = AccessTheWebAsync();

Gibi AccessTheWebAsync, startButton_Click zaman uyumsuz görev sonuçlarına bağlı olmadığından çalışma ile devam edebilirsiniz (getLengthTask) görev beklediğin kadar.Bu çalışma şu çıktı satırları temsil eder.

FOUR:  Back in startButton_Click.
           Task getLengthTask is started.
           About to await getLengthTask -- no caller to return to.

İlerlemenizi startButton_Click ne zaman askıya getLengthTask beklediğin.Aşağıdaki atama deyimini askıya startButton_Click kadar AccessTheWebAsync tamamlandı.

Dim contentLength As Integer = Await getLengthTask
int contentLength = await getLengthTask;

Aşağıdaki çizimde, akış denetiminin await ifadesinden okları Göster AccessTheWebAsync için bir değer atama için getLengthTasknormal işleme, ardından startButton_Click kadar getLengthTask beklediğin.

Adım dört

Hh873191.collapse_all(tr-tr,VS.110).gifBEŞ adım

Zaman client.GetStringAsync tam olarak işleme sinyalleri AccessTheWebAsync Askı durumundan Serbest ve await deyimin devam edebilirsiniz.Aşağıdaki satırları içeren bir çıkış işlemleri sürdürme temsil eder.

FIVE:  Back in AccessTheWebAsync.
           Task getStringTask is complete.
           Processing the return statement.
           Exiting from AccessTheWebAsync.

Return ifadesinin işlenen urlContents.Length, görev içinde saklanır, AccessTheWebAsync döndürür.Bu değerden await ifadeyi alır getLengthTask , startButton_Click.

Aşağıdaki resim denetiminin sonunda aktarımını göstermektedir client.GetStringAsync (ve getStringTask) tamamlandığında.

Adım beş

AccessTheWebAsyncTamamlama ve denetim çalışmaları döner startButton_Click, tamamlanması bekleniyor.

Hh873191.collapse_all(tr-tr,VS.110).gifAdım altı

Zaman AccessTheWebAsync tam işleme sinyalleri await ifadesinde geçen devam edebilir startButton_Async.Aslında, programın başka bir şey yapmak için vardır.

Çıktı aşağıdaki satırları işleme içinde sürdürme temsil eden startButton_Async:

SIX:   Back in startButton_Click.
           Task getLengthTask is finished.
           Result from AccessTheWebAsync is stored in contentLength.
           About to display contentLength and exit.

Await ifadeyi alır getLengthTask için return ifadesinin içinde işlenen tamsayı değeri AccessTheWebAsync.Aşağıdaki deyim, bu değeri atar contentLength değişkeni.

Dim contentLength As Integer = Await getLengthTask
int contentLength = await getLengthTask;

Aşağıdaki resim denetiminden dönüşünü gösterir AccessTheWebAsync için startButton_Click.

Adım altı

Ayrıca bkz.

Görevler

İzlenecek yol: zaman uyumsuz kullanarak Web'e erişme ve (C# ve Visual Basic) beklemek

İzlenecek Yol: Hata Ayıklayıcıyı Zaman Uyumsuz Yöntemlerle Kullanma

Kavramlar

Zaman uyumsuz zaman uyumsuz programlama ve beklemek (C# ve Visual Basic)

Zaman uyumsuz dönüş türleri (C# ve Visual Basic)

Diğer Kaynaklar

Zaman uyumsuz örnek: Akış denetimi içerisinde zaman uyumsuz programlar (C# ve Visual Basic)