Walkthrough: Async kullanarak Web'e erişim ve bekleme (C#)Walkthrough: Accessing the Web by Using async and await (C#)

Async/await özelliklerini kullanarak daha kolay ve sezgisel bir şekilde asynchronous programları yazabilirsiniz.You can write asynchronous programs more easily and intuitively by using async/await features. Senkron koda benzeyen bir senkron kod yazabilir ve derleyicinin asynchronous kodunun genellikle gerektirdiği zor geri arama işlevlerini ve devamlarını işlemesine izin verebilirsiniz.You can write asynchronous code that looks like synchronous code and let the compiler handle the difficult callback functions and continuations that asynchronous code usually entails.

Async özelliği hakkında daha fazla bilgi için, async ile Asynchronous Programming'e bakın ve (C#) bekleyin.For more information about the Async feature, see Asynchronous Programming with async and await (C#).

Bu gözden geçirme, web siteleri listesindeki bayt sayısını özetleyen eşzamanlı bir Windows Presentation Foundation (WPF) uygulamasıyla başlar.This walkthrough starts with a synchronous Windows Presentation Foundation (WPF) application that sums the number of bytes in a list of websites. İzthrough daha sonra yeni özellikleri kullanarak uygulamayı asynchronous çözüme dönüştürür.The walkthrough then converts the application to an asynchronous solution by using the new features.

Uygulamaları kendiniz oluşturmak istemiyorsanız, Async Örnek: Web Walkthrough (C# ve Visual Basic) erişimindirebilirsiniz.If you don't want to build the applications yourself, you can download Async Sample: Accessing the Web Walkthrough (C# and Visual Basic).

Not

Örnekleri çalıştırmak için Visual Studio 2012 veya daha yeni ve .NET Framework 4.5 veya daha yeni bilgisayarınıza yüklü olması gerekir.To run the examples, you must have Visual Studio 2012 or newer and the .NET Framework 4.5 or newer installed on your computer.

WPF uygulaması oluşturmaCreate a WPF application

  1. Visual Studio’yu çalıştırın.Start Visual Studio.

  2. Menü çubuğundaYeni > Proje yi seçin. > On the menu bar, choose File > New > Project.

    Yeni Proje iletişim kutusu açılır.The New Project dialog box opens.

  3. Yüklü Şablonlar bölmesinde Visual C#'ı seçin ve ardından proje türleri listesinden WPF Uygulamasını seçin.In the Installed Templates pane, choose Visual C#, and then choose WPF Application from the list of project types.

  4. Ad metin kutusuna AsyncExampleWPFgirin ve ardından Tamam düğmesini seçin.In the Name text box, enter AsyncExampleWPF, and then choose the OK button.

    Yeni proje Çözüm Gezgini'ndegörünür.The new project appears in Solution Explorer.

Basit bir WPF MainWindow tasarlaDesign a simple WPF MainWindow

  1. Visual Studio Code Editor'da MainWindow.xaml sekmesini seçin.In the Visual Studio Code Editor, choose the MainWindow.xaml tab.

  2. Araç Kutusu penceresi görünmüyorsa, Görünüm menüsünü açın ve ardından Araç Kutusu'nuseçin.If the Toolbox window isn’t visible, open the View menu, and then choose Toolbox.

  3. MainWindow penceresine düğme denetimi ve TextBox denetimi ekleyin.Add a Button control and a TextBox control to the MainWindow window.

  4. TextBox denetimini vurgulayın ve Özellikler penceresinde aşağıdaki değerleri ayarlayın:Highlight the TextBox control and, in the Properties window, set the following values:

    • Ad özelliğini resultsTextBox' ' ye ayarlamaSet the Name property to resultsTextBox.

    • Yükseklik özelliğini 250 olarak ayarlayın.Set the Height property to 250.

    • Genişlik özelliğini 500 olarak ayarlayın.Set the Width property to 500.

    • Metin sekmesinde, Lucida Console veya Global Monospace gibi tek boşluklu bir yazı tipi belirtin.On the Text tab, specify a monospaced font, such as Lucida Console or Global Monospace.

  5. Düğme denetimini vurgulayın ve Özellikler penceresinde aşağıdaki değerleri ayarlayın:Highlight the Button control and, in the Properties window, set the following values:

    • Ad özelliğini startButton' ' ye ayarlamaSet the Name property to startButton.

    • İçerik özelliğinin değerini Düğme'den Başlangıçekranına değiştirin.Change the value of the Content property from Button to Start.

  6. Metin kutusunu ve düğmeyi, her ikisi de Ana Pencere penceresinde görünecek şekilde konumlandırın.Position the text box and the button so that both appear in the MainWindow window.

    WPF XAML Tasarımcısı hakkında daha fazla bilgi için Bkz. XAML Designer kullanarak bir kullanıcı arabirimi oluşturma.For more information about the WPF XAML Designer, see Creating a UI by using XAML Designer.

Referans eklemeAdd a reference

  1. Çözüm Gezgini'ndeprojenizin adını vurgulayın.In Solution Explorer, highlight your project's name.

  2. Menü çubuğunda, Project > Add Reference'ıseçin.On the menu bar, choose Project > Add Reference.

    Başvuru Yöneticisi iletişim kutusu görüntülenir.The Reference Manager dialog box appears.

  3. İletişim kutusunun üst kısmında, projenizin .NET Framework 4.5 veya daha yüksek hedeflediğini doğrulayın.At the top of the dialog box, verify that your project is targeting the .NET Framework 4.5 or higher.

  4. Derlemeler kategorisinde, henüz seçilmemişse Çerçeve'yi seçin.In the Assemblies category, choose Framework if it isn’t already chosen.

  5. Adlar listesinde System.Net.Http onay kutusunu seçin.In the list of names, select the System.Net.Http check box.

  6. İletişim kutusunu kapatmak için Tamam düğmesini seçin.Choose the OK button to close the dialog box.

Yönergeleri kullanarak gerekli eklemeAdd necessary using directives

  1. Çözüm Gezgini'nde, MainWindow.xaml.cs için kısayol menüsünü açın ve ardından Kodu Görüntüle'yiseçin.In Solution Explorer, open the shortcut menu for MainWindow.xaml.cs, and then choose View Code.

  2. Zaten mevcut using değillerse kod dosyasının en üstüne aşağıdaki yönergeleri ekleyin.Add the following using directives at the top of the code file if they’re not already present.

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

Eşzamanlı bir uygulama oluşturmaCreate a synchronous app

  1. Tasarım penceresinde, MainWindow.xaml, MainWindow.xaml.cs olay Start işleyicisi startButton_Click oluşturmak için Başlat düğmesini çift tıklatın.In the design window, MainWindow.xaml, double-click the Start button to create the startButton_Click event handler in MainWindow.xaml.cs.

  2. MainWindow.xaml.cs, aşağıdaki kodu gövdeye startButton_Clickkopyalayın:In MainWindow.xaml.cs, copy the following code into the body of startButton_Click:

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

    Kod, SumPageSizesuygulamayı yönlendiren yöntemi çağırır ve denetim startButton_Click.The code calls the method that drives the application, SumPageSizes, and displays a message when control returns to startButton_Click.

  3. Senkron çözümün kodu aşağıdaki dört yöntemi içerir:The code for the synchronous solution contains the following four methods:

    • SumPageSizes, web sayfası URL'lerinin bir SetUpURLList listesini alır GetURLContents DisplayResults ve daha sonra aramaları ve her URL işlemek için.SumPageSizes, which gets a list of webpage URLs from SetUpURLList and then calls GetURLContents and DisplayResults to process each URL.

    • SetUpURLList, web adreslerinin listesini yapar ve döndürür.SetUpURLList, which makes and returns a list of web addresses.

    • GetURLContents, her web sitesinin içeriğini indirir ve bir bayt dizisi olarak içeriğini döndürür.GetURLContents, which downloads the contents of each website and returns the contents as a byte array.

    • DisplayResults, her URL için bayt dizisindebayt sayısını görüntüler.DisplayResults, which displays the number of bytes in the byte array for each URL.

    Aşağıdaki dört yöntemi kopyalayın ve MainWindow.xaml.cs startButton_Click olay işleyicisinin altına yapıştırın:Copy the following four methods, and then paste them under the startButton_Click event handler in MainWindow.xaml.cs:

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

Senkron çözümü test edinTest the synchronous solution

Programı çalıştırmak için F5 tuşunu seçin ve ardından Başlat düğmesini seçin.Choose the F5 key to run the program, and then choose the Start button.

Aşağıdaki listeye benzeyen çıktı görünmelidir:Output that resembles the following list should appear:

msdn.microsoft.com/library/windows/apps/br211380.aspx        383832
msdn.microsoft.com                                            33964
msdn.microsoft.com/library/hh290136.aspx               225793
msdn.microsoft.com/library/ee256749.aspx               143577
msdn.microsoft.com/library/hh290138.aspx               237372
msdn.microsoft.com/library/hh290140.aspx               128279
msdn.microsoft.com/library/dd470362.aspx               157649
msdn.microsoft.com/library/aa578028.aspx               204457
msdn.microsoft.com/library/ms404677.aspx               176405
msdn.microsoft.com/library/ff730837.aspx               143474

Total bytes returned:  1834802

Control returned to startButton_Click.

Sayımların görüntülenmesinin birkaç saniye sürdüğünü unutmayın.Notice that it takes a few seconds to display the counts. Bu süre zarfında, istenen kaynakların karşıdan yüklenmesini beklerken UI iş parçacığı engellenir.During that time, the UI thread is blocked while it waits for requested resources to download. Sonuç olarak, Başlat düğmesini seçtikten sonra ekran penceresini taşıyamaz, en üst düzeye çıkaramaz, simge durumuna indiremez ve hatta kapatamazsınız.As a result, you can't move, maximize, minimize, or even close the display window after you choose the Start button. Bu çabalar, bayt sayıları görünmeye başlayana kadar başarısız dır.These efforts fail until the byte counts start to appear. Bir web sitesi yanıt vermiyorsa, hangi sitenin başarısız olduğuna dair bir belirti yoktur.If a website isn’t responding, you have no indication of which site failed. Beklemeyi bırakıp programı kapatmak bile zordur.It is difficult even to stop waiting and close the program.

GetURLContents'i eşzamanlı bir yönteme dönüştürmeConvert GetURLContents to an asynchronous method

  1. Senkron çözümü bir asynchronous çözüme dönüştürmek için, başlbaşlamak için en HttpWebRequest GetResponse iyi yer, CopyTo GetURLContents çünkü yönteme ve Stream yönteme yapılan çağrılar uygulamanın web'e eriştiği yerdir.To convert the synchronous solution to an asynchronous solution, the best place to start is in GetURLContents because the calls to the HttpWebRequest method GetResponse and to the Stream method CopyTo are where the application accesses the web. .NET Framework, her iki yöntemin eşzamanlı sürümlerini sağlayarak dönüşümü kolaylaştırır.The .NET Framework makes the conversion easy by supplying asynchronous versions of both methods.

    Kullanılan GetURLContentsyöntemler hakkında daha fazla bilgi WebRequestiçin bkz.For more information about the methods that are used in GetURLContents, see WebRequest.

    Not

    Bu izbindeki adımları izlediğiniz de, birkaç derleyici hatası görüntülenir.As you follow the steps in this walkthrough, several compiler errors appear. Bunları yok sayabilir ve izliğe devam edebilirsiniz.You can ignore them and continue with the walkthrough.

    Üçüncü satırda GetURLContents çağrılan yöntemi asynchronous, görev tabanlı GetResponse GetResponseAsync yönteme değiştirin.Change the method that's called in the third line of GetURLContents from GetResponse to the asynchronous, task-based GetResponseAsync method.

    using (WebResponse response = webReq.GetResponseAsync())
    
  2. GetResponseAsyncbir Task<TResult>' yi döndürür.GetResponseAsync returns a Task<TResult>. Bu durumda, görev iade değişkeni, , TResulttürü WebResponsevardır.In this case, the task return variable, TResult, has type WebResponse. Görev, istenen veriler karşıdan WebResponse yüklendikten ve görev tamamlanmak üzere çalıştırıldıktan sonra gerçek bir nesne oluşturma sözüdür.The task is a promise to produce an actual WebResponse object after the requested data has been downloaded and the task has run to completion.

    Görevden WebResponse değeri almak için, GetResponseAsyncaşağıdaki kodun gösterdiği gibi çağrıya bir bekleyen işleci uygulayın.To retrieve the WebResponse value from the task, apply an await operator to the call to GetResponseAsync, as the following code shows.

    using (WebResponse response = await webReq.GetResponseAsync())
    

    İşleç, await GetURLContentsbeklenen görev tamamlanana kadar geçerli yöntemin yürütülmesini askıya adatır.The await operator suspends the execution of the current method, GetURLContents, until the awaited task is complete. Bu arada, denetim geçerli yöntemin arayan döndürür.In the meantime, control returns to the caller of the current method. Bu örnekte, geçerli GetURLContentsyöntem ve arayan SumPageSizes.In this example, the current method is GetURLContents, and the caller is SumPageSizes. Görev tamamlandığında, vaat edilen WebResponse nesne beklenen görevin değeri olarak üretilir ve responsedeğişkene atanır.When the task is finished, the promised WebResponse object is produced as the value of the awaited task and assigned to the variable response.

    Önceki deyim, ne olduğunu açıklığa kavuşturmak için aşağıdaki iki ifadeye ayrılabilir.The previous statement can be separated into the following two statements to clarify what happens.

    //Task<WebResponse> responseTask = webReq.GetResponseAsync();
    //using (WebResponse response = await responseTask)
    

    Arama bir webReq.GetResponseAsync Task(Of WebResponse) veya Task<WebResponse>.The call to webReq.GetResponseAsync returns a Task(Of WebResponse) or Task<WebResponse>. Daha sonra WebResponse değeri almak için göreve bir bekleme işleci uygulanır.Then an await operator is applied to the task to retrieve the WebResponse value.

    Async yönteminizin görevi tamamlamasına bağlı olmayan bir çalışması varsa, yöntem bu iki deyim arasında, async yöntemine yapılan çağrıdan await sonra ve işleç uygulanmadan önce bu çalışmaya devam edebilir.If your async method has work to do that doesn’t depend on the completion of the task, the method can continue with that work between these two statements, after the call to the async method and before the await operator is applied. Örneğin, async ve await (C#) kullanarak paralel olarak birden çok web isteği nasıl yapılır ve Task.WhenAll (C#) kullanarak async walkthrough genişletmek için nasılbakın.For examples, see How to make multiple web requests in parallel by using async and await (C#) and How to extend the async walkthrough by using Task.WhenAll (C#).

  3. Önceki adımda await işleci eklediğiniz için derleyici hatası oluşur.Because you added the await operator in the previous step, a compiler error occurs. İşleç yalnızca async değiştirici ile işaretlenmiş yöntemlerde kullanılabilir.The operator can be used only in methods that are marked with the async modifier. Çağrıyı bir çağrıyla değiştirmek için CopyTo dönüşüm adımlarını yinelerken hatayı CopyToAsyncyoksay.Ignore the error while you repeat the conversion steps to replace the call to CopyTo with a call to CopyToAsync.

    • 'ye çağrılan yöntemin adını CopyToAsyncdeğiştirin.Change the name of the method that’s called to CopyToAsync.

    • Veya CopyTo CopyToAsync yöntem bağımsız değişkenine contentbayt kopyalar ve anlamlı bir değer döndürmez.The CopyTo or CopyToAsync method copies bytes to its argument, content, and doesn’t return a meaningful value. Senkron sürümde, çağrı bir CopyTo değer döndürmeyen basit bir ifadedir.In the synchronous version, the call to CopyTo is a simple statement that doesn't return a value. Asynchronous sürümü, CopyToAsyncbir Task.The asynchronous version, CopyToAsync, returns a Task. Görev "Görev(void)" gibi işlevgörür ve yöntemin beklenen olmasını sağlar.The task functions like "Task(void)" and enables the method to be awaited. Aşağıdaki Await await kodun gösterdiği CopyToAsyncgibi, çağrıya uygulayın veya çağrıya uygulayın.Apply Await or await to the call to CopyToAsync, as the following code shows.

      await responseStream.CopyToAsync(content);
      

      Önceki deyim, aşağıdaki iki kod satırını kısaltır.The previous statement abbreviates the following two lines of code.

      // CopyToAsync returns a Task, not a Task<T>.
      //Task copyTask = responseStream.CopyToAsync(content);
      
      // When copyTask is completed, content contains a copy of
      // responseStream.
      //await copyTask;
      
  4. Yapılması gereken tek GetURLContents şey yöntem imzasını ayarlamaktır.All that remains to be done in GetURLContents is to adjust the method signature. İşleç'i await yalnızca async değiştirici ile işaretlenmiş yöntemlerde kullanabilirsiniz.You can use the await operator only in methods that are marked with the async modifier. Aşağıdaki kodun gösterdiği gibi, yöntemi bir async yöntemiolarak işaretlemek için değiştirici ekleyin.Add the modifier to mark the method as an async method, as the following code shows.

    private async byte[] GetURLContents(string url)
    
  5. Bir async yönteminin dönüş türü Task Task<TResult>yalnızca void , veya C# olabilir.The return type of an async method can only be Task, Task<TResult>, or void in C#. Genellikle, bir dönüş void türü yalnızca gerekli olduğu bir void async olay işleyicisi kullanılır.Typically, a return type of void is used only in an async event handler, where void is required. Diğer durumlarda, tamamlanan Task(T) yöntemde T türü bir değer döndüren bir iade deyimi varsa ve tamamlanan yöntem anlamlı bir değer döndürmüyorsa kullanırsınız. TaskIn other cases, you use Task(T) if the completed method has a return statement that returns a value of type T, and you use Task if the completed method doesn’t return a meaningful value. Task İade türünü "Görev(boşluk)" anlamında düşünebilirsiniz.You can think of the Task return type as meaning "Task(void)."

    Daha fazla bilgi için Bkz. Async İade Türleri (C#).For more information, see Async Return Types (C#).

    Yöntemin GetURLContents bir iade deyimi vardır ve deyim bir bayt dizisini döndürür.Method GetURLContents has a return statement, and the statement returns a byte array. Bu nedenle, async sürümünün dönüş türü, T'nin bir bayt dizisi olduğu Görev(T) türüdür.Therefore, the return type of the async version is Task(T), where T is a byte array. Yöntem imzasında aşağıdaki değişiklikleri yapın:Make the following changes in the method signature:

    • İade türünü Task<byte[]>' le değiştirinChange the return type to Task<byte[]>.

    • Kural olarak, eşişme yöntemleri "Async" ile biten adlar GetURLContentsAsyncvardır, bu nedenle yöntemi yeniden adlandırın.By convention, asynchronous methods have names that end in "Async," so rename the method GetURLContentsAsync.

    Aşağıdaki kod bu değişiklikleri gösterir.The following code shows these changes.

    private async Task<byte[]> GetURLContentsAsync(string url)
    

    Bu birkaç değişiklikle, GetURLContents eşzamanlı bir yönteme dönüştürme tamamlandı.With those few changes, the conversion of GetURLContents to an asynchronous method is complete.

SumPageSizes'ı eşzamanlı bir yönteme dönüştürmeConvert SumPageSizes to an asynchronous method

  1. Önceki SumPageSizesyordamdan gelen adımları yineleyin.Repeat the steps from the previous procedure for SumPageSizes. İlk olarak, aramayı GetURLContents eşzamanlı çağrıya çevirin.First, change the call to GetURLContents to an asynchronous call.

    • Daha önce GetURLContents GetURLContentsAsyncyapmadıysanız, "bu yöntemden" olarak çağrılan yöntemin adını değiştirin.Change the name of the method that’s called from GetURLContents to GetURLContentsAsync, if you haven't already done so.

    • Bayt dizi GetURLContentsAsync değerini elde etmek için dönen göreve uygulayın. awaitApply await to the task that GetURLContentsAsync returns to obtain the byte array value.

    Aşağıdaki kod bu değişiklikleri gösterir.The following code shows these changes.

    byte[] urlContents = await GetURLContentsAsync(url);
    

    Önceki atama, aşağıdaki iki kod satırını kısaltır.The previous assignment abbreviates the following two lines of code.

    // GetURLContentsAsync returns a Task<T>. At completion, the task
    // produces a byte array.
    //Task<byte[]> getContentsTask = GetURLContentsAsync(url);
    //byte[] urlContents = await getContentsTask;
    
  2. Yöntemin imzasında aşağıdaki değişiklikleri yapın:Make the following changes in the method's signature:

    • Yöntemi async değiştirici ile işaretleyin.Mark the method with the async modifier.

    • Yöntem adına "Async" ekleyin.Add "Async" to the method name.

    • T. için bir değer SumPageSizesAsync döndürmediği için bu sefer görev iade değişkeni yoktur, T, bu sefer (Yöntemin deyimi yoktur.) return Ancak, yöntem beklenilebilir bir dönmek Task gerekir.There is no task return variable, T, this time because SumPageSizesAsync doesn’t return a value for T. (The method has no return statement.) However, the method must return a Task to be awaitable. Bu nedenle, yöntemin dönüş void türünü Task' den ' e değiştirin.Therefore, change the return type of the method from void to Task.

    Aşağıdaki kod bu değişiklikleri gösterir.The following code shows these changes.

    private async Task SumPageSizesAsync()
    

    SumPageSizes Dönüştürme SumPageSizesAsync tamamlandı.The conversion of SumPageSizes to SumPageSizesAsync is complete.

startButton_Click bir eşzamanlı yönteme dönüştürmeConvert startButton_Click to an asynchronous method

  1. Olay işleyicisinde, çağrılan yöntemin SumPageSizes adını SumPageSizesAsync, henüz yapmadıysanız değiştirin.In the event handler, change the name of the called method from SumPageSizes to SumPageSizesAsync, if you haven’t already done so.

  2. Bir SumPageSizesAsync async yöntemi olduğundan, sonucu beklemek için olay işleyicisi kodu değiştirin.Because SumPageSizesAsync is an async method, change the code in the event handler to await the result.

    Çağrıyı SumPageSizesAsync yansıtmak için CopyToAsync GetURLContentsAsyncçağrı.The call to SumPageSizesAsync mirrors the call to CopyToAsync in GetURLContentsAsync. Arama bir Taskdöndürür, bir Task(T).The call returns a Task, not a Task(T).

    Önceki yordamlarda olduğu gibi, bir veya iki deyim kullanarak aramayı dönüştürebilirsiniz.As in previous procedures, you can convert the call by using one statement or two statements. Aşağıdaki kod bu değişiklikleri gösterir.The following code shows these changes.

    // One-step async call.
    await SumPageSizesAsync();
    
    // Two-step async call.
    //Task sumTask = SumPageSizesAsync();
    //await sumTask;
    
  3. İşleme yanlışlıkla yeniden girmesini önlemek için Başlat düğmesini startButton_Click devre dışı katmak için en üstteki ifadeyi ekleyin.To prevent accidentally reentering the operation, add the following statement at the top of startButton_Click to disable the Start button.

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

    Olay işleyicisinin sonundaki düğmeyi yeniden etkinleştirebilirsiniz.You can reenable the button at the end of the event handler.

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

    Reentrancy hakkında daha fazla bilgi için, Async Apps (C#) içinde Reentrancy Işlemebakın.For more information about reentrancy, see Handling Reentrancy in Async Apps (C#).

  4. Son olarak, async olay işleyicisi bekliyor SumPagSizesAsyncböylece bildirime değiştirici ekleyin.Finally, add the async modifier to the declaration so that the event handler can await SumPagSizesAsync.

    private async void startButton_Click(object sender, RoutedEventArgs e)
    

    Genellikle, olay işleyicilerinin adları değiştirilmez.Typically, the names of event handlers aren’t changed. Olay işleyicileri döndürmesi Task voidgerektiğinden, iade türü değiştirilmez.The return type isn’t changed to Task because event handlers must return void.

    Projenin senkron işlemden asynchronous işleme ye dönüştürülmesi tamamlandı.The conversion of the project from synchronous to asynchronous processing is complete.

Asynchronous çözeltisini test edinTest the asynchronous solution

  1. Programı çalıştırmak için F5 tuşunu seçin ve ardından Başlat düğmesini seçin.Choose the F5 key to run the program, and then choose the Start button.

  2. Senkron çözeltinin çıktısını andıran çıktı görünmelidir.Output that resembles the output of the synchronous solution should appear. Ancak, aşağıdaki farklılıklara dikkat edin.However, notice the following differences.

    • İşlem tamamlandıktan sonra tüm sonuçlar aynı anda oluşmaz.The results don’t all occur at the same time, after the processing is complete. Örneğin, her iki program startButton_Click da metin kutusunu temizleyen bir satır içerir.For example, both programs contain a line in startButton_Click that clears the text box. Amaç, bir sonuç kümesi ortaya çıktıktan sonra ikinci kez Başlat düğmesini seçerseniz, çalıştırmalar arasındaki metin kutusunu temizlemektir.The intent is to clear the text box between runs if you choose the Start button for a second time, after one set of results has appeared. Senkron sürümde, metin kutusu, karşıdan yüklemeler tamamlandığında ve Kullanıcı Arabirimi iş parçacığı başka işler yapmakta özgür olduğunda, sayımlar ikinci kez görünmeden hemen önce temizlenir.In the synchronous version, the text box is cleared just before the counts appear for the second time, when the downloads are completed and the UI thread is free to do other work. Eşzamanlı sürümde, başlat düğmesini seçtikten hemen sonra metin kutusu temizlenir.In the asynchronous version, the text box clears immediately after you choose the Start button.

    • En önemlisi, UI iş parçacığı indirme sırasında engellenmez.Most importantly, the UI thread isn’t blocked during the downloads. Web kaynakları karşıdan yüklenirken, sayılırken ve görüntülenirken pencereyi taşıyabilir veya yeniden boyutlandırabilirsiniz.You can move or resize the window while the web resources are being downloaded, counted, and displayed. Web sitelerinden biri yavaşsa veya yanıt vermiyorsa, Kapat düğmesini (sağ üst köşedeki kırmızı alandaki x) seçerek işlemi iptal edebilirsiniz.If one of the websites is slow or not responding, you can cancel the operation by choosing the Close button (the x in the red field in the upper-right corner).

GetURLContentsAsync yöntemini bir .NET Framework yöntemiyle değiştirinReplace method GetURLContentsAsync with a .NET Framework method

  1. .NET Framework 4.5, kullanabileceğiniz birçok async yöntemi sağlar.The .NET Framework 4.5 provides many async methods that you can use. Bunlardan biri, HttpClient yöntem GetByteArrayAsync(String), bu walkthrough için gereken sadece ne yapar.One of them, the HttpClient method GetByteArrayAsync(String), does just what you need for this walkthrough. Daha önceki bir yordamda oluşturduğunuz GetURLContentsAsync yöntem yerine kullanabilirsiniz.You can use it instead of the GetURLContentsAsync method that you created in an earlier procedure.

    İlk adım yöntemde HttpClient SumPageSizesAsyncbir nesne oluşturmaktır.The first step is to create an HttpClient object in method SumPageSizesAsync. Yöntemin başında aşağıdaki bildirimi ekleyin.Add the following declaration at the start of the method.

    // Declare an HttpClient object and increase the buffer size. The
    // default buffer size is 65,536.
    HttpClient client =
        new HttpClient() { MaxResponseContentBufferSize = 1000000 };
    
  2. Yönteme SumPageSizesAsync, GetURLContentsAsync yapılan çağrıyı HttpClient yönteme yapılan bir çağrıyla değiştirin.In SumPageSizesAsync, replace the call to your GetURLContentsAsync method with a call to the HttpClient method.

    byte[] urlContents = await client.GetByteArrayAsync(url);
    
  3. Yazdığınız GetURLContentsAsync yöntemi kaldırın veya yorum yapın.Remove or comment out the GetURLContentsAsync method that you wrote.

  4. Programı çalıştırmak için F5 tuşunu seçin ve ardından Başlat düğmesini seçin.Choose the F5 key to run the program, and then choose the Start button.

    Projenin bu sürümünün davranışı, "Asynchronous çözümünü sınamak için" yordamının açıkladığı davranışla eşleşmelidir, ancak sizden daha az çaba göstermelidir.The behavior of this version of the project should match the behavior that the "To test the asynchronous solution" procedure describes but with even less effort from you.

Örnek kodExample code

Aşağıdaki kod, yazdığınız eşzamanlı GetURLContentsAsync yöntemi kullanarak eşzamanlı bir çözümden eşzamanlı bir çözüme dönüştürmenin tam örneğini içerir.The following code contains the full example of the conversion from a synchronous to an asynchronous solution by using the asynchronous GetURLContentsAsync method that you wrote. Orijinal, eşzamanlı çözüme güçlü bir şekilde benzediğine dikkat edin.Notice that it strongly resembles the original, synchronous solution.

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

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

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

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

            resultsTextBox.Clear();

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

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

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

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

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

            var total = 0;

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

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

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

                DisplayResults(url, urlContents);

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

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

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

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

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

            // The previous statement abbreviates the following two statements.

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

                    // The previous statement abbreviates the following two statements.

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

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

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

Aşağıdaki kod, GetByteArrayAsyncyöntemi kullanan çözümün tam HttpClient örneğini içerir.The following code contains the full example of the solution that uses the HttpClient method, GetByteArrayAsync.

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

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

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

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

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

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

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

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

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

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

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

            var total = 0;

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

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

                DisplayResults(url, urlContents);

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

            // Display the total count for all of the websites.
            resultsTextBox.Text +=
                $"\r\n\r\nTotal bytes returned:  {total}\r\n";
        }

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

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

Ayrıca bkz.See also