İzlenecek yol: Async ve Await Kullanarak Web'e Erişme (C# ve Visual Basic)
Getirilmiştir özelliklerini kullanarak daha kolay ve postayı kolayca zaman uyumsuz programlar yazabilirsiniz Visual Studio 2012.Zaman uyumlu bir kod gibi görünüyor zaman uyumsuz kod yazmak ve derleyici zor geri arama işlevleri ve zaman uyumsuz kod genellikle kapsar devamlılığını sağlar.
Zaman uyumsuz özelliği hakkında daha fazla bilgi için bkz: Async ve Await ile Zaman Uyumsuz Programlama (C# ve Visual Basic).
Bu izlenecek yolda, Web sitelerinin listesini bayt sayısı toplamını alan bir zaman uyumlu Windows Presentation Foundation (wpf) uygulaması ile başlar.İzlenecek yol, zaman uyumsuz bir çözüm uygulamaya sonra yeni özellikleri kullanarak dönüştürür.
Kendinizi uygulamaları oluşturmak istemiyorsanız, karşıdan yükleyebileceğiniz "zaman uyumsuz örnek: Web gözden geçirme (C# ve Visual Basic) erişme" dan Developer kod örnekleri.
Bu yönergede, aşağıdaki görevleri tamamlayın:
Create a WPF application.
Design a simple WPF MainWindow window.
Add a reference.
Add Imports statements or using directives.
Create a synchronous solution.
Test the synchronous solution.
Convert GetURLContents to an asynchronous method.
Convert SumPageSizes to an asynchronous method.
Convert startButton_Click to an asynchronous method.
Test the asynchronous solution.
Replace GetURLContentsAsync with a .NET Framework method.
Complete Code Examples from the Walkthrough
Önkoşullar
Visual Studio 2012Bilgisayarınızda yüklü olmalıdır.Daha fazla bilgi için bkz: Microsoft Web sitesini ziyaret.
wpf uygulaması oluşturma
Visual &Studio'yu başlatın.
Menü çubuğunda Dosya, Yeni, Proje'yi seçin.
Yeni Proje iletişim kutusu açılır.
İçinde Yüklü Şablonlar bölmesinde seçin Visual Basic veya **Visual C#**ve sonra seçin wpf uygulaması proje türleri listesinde.
İçinde adı metin kutusuna girin AsyncExampleWPFve sonra Tamam düğmesi.
Çözüm Gezgini'nde yeni proje görüntülenir.
Basit wpf MainWindow tasarlamak için
Visual Studio Kod Düzenleyicisi'nde seçin MainWindow.xaml sekme.
Araç görünür, açık değilse Pencere Görünüm menüsünde ve sonra seçin araç.
Ekleme bir düğmesini denetimi ve bir TextBox için kontrol MainWindow pencere.
Vurgulama TextBox denetimi hem de özelliklerini penceresinde, aşağıdaki değerleri ayarlayın:
Set adı özelliğini resultsTextBox.
Set yüksekliği 250 özelliğine.
Set genişliği 500 özelliği.
Üzerinde metin sekmesinde, Lucida Console veya genel tek aralýklý gibi tek boşluklu bir yazı tipi belirtin.
Vurgulama düğmesini denetimi hem de Özellikler penceresinde, aşağıdaki değerleri ayarlayın:
Set adı özelliğini startButton.
Değeri değiştirmek İçerik özelliğinden düğmesini için Start.
Her ikisi de görünür metin kutusu ve düğme konumlandırın, böylece MainWindow pencere.
wpf xaml Tasarımcısı hakkında daha fazla bilgi için bkz: Creating a UI by using XAML Designer.
Bir başvuru eklemek için
İçinde Çözüm Gezgini, projenizin adını vurgulayın.
Menü çubuğunda Seç Proje, Add Reference.
Reference Manager iletişim kutusu görüntülenir.
İletişim kutusunun üstündeki projeniz .NET Framework 4.5 hedeflediği doğrulayın.
İçinde derlemeleri alanında seçin Framework tercih değildir.
Adlar listesinde seçin System.Net.Http onay kutusu.
Seçim Tamam düğmesini tıklatarak iletişim kutusunu kapatın.
Gerekli Imports ifadelerini eklemek veya yönergeleri kullanma
İç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.
Aşağıdaki Imports ifadeleri (Visual Basic'te) veya using zaten mevcut değillerse kod dosyasının en üstündeki yönergeleri (C#).
Imports System.Net.Http Imports System.Net Imports System.IO
using System.Net.Http; using System.Net; using System.IO;
Zaman uyumlu bir uygulama oluşturmak için
Tasarım penceresinde, MainWindow.xaml, çift Start oluşturmak için düğme startButton_Click MainWindow.xaml.vb veya MainWindow.xaml.cs olay işleyicisinde.Alternatif olarak, Vurgu Başlat , Seç düğmesini Seçili öğeler için olay işleyicileri simgesini özellikleri penceresinde ve enter startButton_Click , 'ı tıklatın metin kutusu.
MainWindow.xaml.vb veya MainWindow.xaml.cs, gövdesine aşağıdaki kodu kopyalayın startButton_Click.
resultsTextBox.Clear() SumPageSizes() resultsTextBox.Text &= vbCrLf & "Control returned to startButton_Click."
resultsTextBox.Clear(); SumPageSizes(); resultsTextBox.Text += "\r\nControl returned to startButton_Click.";
Kod uygulama sürücüleri yöntemini çağırır SumPageSizesve denetim döndüğünde bir ileti görüntüler startButton_Click.
Zaman uyumlu çözüm kodunu aşağıdaki dört yöntem içerir:
SumPageSizes, Web sayfası URL'lerine karşı bir listesini alır SetUpURLList ve daha sonra GetURLContents ve DisplayResults her url işlemek için.
SetUpURLList, yapar ve web adreslerinin bir listesini döndürür.
GetURLContents, her Web sitesi içeriğini karşıdan yükler ve içeriği bir bayt dizisi döndürür.
DisplayResults, görüntüleyen bayt bayt dizisi, her url için.
Aşağıdaki dört yöntem kopyalayıp yapıştırın altlarında startButton_Click MainWindow.xaml.vb veya MainWindow.xaml.cs olay işleyicisinde.
Private Sub SumPageSizes() ' Make a list of web addresses. Dim urlList As List(Of String) = SetUpURLList() Dim total = 0 For Each url In urlList ' GetURLContents returns the contents of url as a byte array. Dim urlContents As Byte() = GetURLContents(url) DisplayResults(url, urlContents) ' Update the total. total += urlContents.Length Next ' Display the total count for all of the web addresses. resultsTextBox.Text &= String.Format(vbCrLf & vbCrLf & "Total bytes returned: {0}" & vbCrLf, total) End Sub Private Function SetUpURLList() As List(Of String) Dim urls = New List(Of String) From { "https://msdn.microsoft.com/library/windows/apps/br211380.aspx", "https://msdn.microsoft.com", "https://msdn.microsoft.com/en-us/library/hh290136.aspx", "https://msdn.microsoft.com/en-us/library/ee256749.aspx", "https://msdn.microsoft.com/en-us/library/hh290138.aspx", "https://msdn.microsoft.com/en-us/library/hh290140.aspx", "https://msdn.microsoft.com/en-us/library/dd470362.aspx", "https://msdn.microsoft.com/en-us/library/aa578028.aspx", "https://msdn.microsoft.com/en-us/library/ms404677.aspx", "https://msdn.microsoft.com/en-us/library/ff730837.aspx" } Return urls End Function Private Function GetURLContents(url As String) As Byte() ' The downloaded resource ends up in the variable named content. Dim content = New MemoryStream() ' Initialize an HttpWebRequest for the current URL. Dim webReq = CType(WebRequest.Create(url), HttpWebRequest) ' Send the request to the Internet resource and wait for ' the response. ' Note: you can't use HttpWebRequest.GetResponse in a Windows Store app. Using response As WebResponse = webReq.GetResponse() ' Get the data stream that is associated with the specified URL. Using responseStream As Stream = response.GetResponseStream() ' Read the bytes in responseStream and copy them to content. responseStream.CopyTo(content) End Using End Using ' Return the result as a byte array. Return content.ToArray() End Function Private Sub DisplayResults(url As String, content As Byte()) ' Display the length of each website. The string format ' is designed to be used with a monospaced font, such as ' Lucida Console or Global Monospace. Dim bytes = content.Length ' Strip off the "http://". Dim displayURL = url.Replace("http://", "") resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes) End Sub
private void SumPageSizes() { // Make a list of web addresses. List<string> urlList = SetUpURLList(); var total = 0; foreach (var url in urlList) { // GetURLContents returns the contents of url as a byte array. byte[] urlContents = GetURLContents(url); DisplayResults(url, urlContents); // Update the total. total += urlContents.Length; } // Display the total count for all of the web addresses. resultsTextBox.Text += string.Format("\r\n\r\nTotal bytes returned: {0}\r\n", total); } private List<string> SetUpURLList() { var urls = new List<string> { "https://msdn.microsoft.com/library/windows/apps/br211380.aspx", "https://msdn.microsoft.com", "https://msdn.microsoft.com/en-us/library/hh290136.aspx", "https://msdn.microsoft.com/en-us/library/ee256749.aspx", "https://msdn.microsoft.com/en-us/library/hh290138.aspx", "https://msdn.microsoft.com/en-us/library/hh290140.aspx", "https://msdn.microsoft.com/en-us/library/dd470362.aspx", "https://msdn.microsoft.com/en-us/library/aa578028.aspx", "https://msdn.microsoft.com/en-us/library/ms404677.aspx", "https://msdn.microsoft.com/en-us/library/ff730837.aspx" }; return urls; } private byte[] GetURLContents(string url) { // The downloaded resource ends up in the variable named content. var content = new MemoryStream(); // Initialize an HttpWebRequest for the current URL. var webReq = (HttpWebRequest)WebRequest.Create(url); // Send the request to the Internet resource and wait for // the response. // 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 "http://". var displayURL = url.Replace("http://", ""); resultsTextBox.Text += string.Format("\n{0,-58} {1,8}", displayURL, bytes); }
Zaman uyumlu çözümü test etmek için
Seçim programını çalıştırın ve sonra seçmek için F5 tuşuna Start düğmesi.
Aşağıdaki listede benzer bir çıktı görüntülenir.
msdn.microsoft.com/library/windows/apps/br211380.aspx 383832 msdn.microsoft.com 33964 msdn.microsoft.com/en-us/library/hh290136.aspx 225793 msdn.microsoft.com/en-us/library/ee256749.aspx 143577 msdn.microsoft.com/en-us/library/hh290138.aspx 237372 msdn.microsoft.com/en-us/library/hh290140.aspx 128279 msdn.microsoft.com/en-us/library/dd470362.aspx 157649 msdn.microsoft.com/en-us/library/aa578028.aspx 204457 msdn.microsoft.com/en-us/library/ms404677.aspx 176405 msdn.microsoft.com/en-us/library/ff730837.aspx 143474 Total bytes returned: 1834802 Control returned to startButton_Click.
Sayıları görüntülemek için birkaç saniye sürer dikkat edin.İstenen kaynaklar karşıdan yüklemek beklerken bu süre içinde UI iş parçacığı engellenir.Sonuç olarak, taşıyamazsınız, en üst düzeye çıkarmak, en aza indirmek veya seçtiğiniz sonra bile görüntü penceresini kapatın Start düğmesi.Bu çalışmalar sonucunda görünmesini bayt sayıları başlatana kadar başarısız.Bir Web sitesinin yanıt vermiyor, hangi sitenin başarısız olduğuna dair hiçbir bilgi vardır.Hatta bekleyen durdurmak ve programı kapatmak zordur.
Bu davranış için karşılaştırma Örnek zaman uyumsuz bir çözüm.
Zaman uyumsuz bir yönteme GetURLContents dönüştürmek için
Zaman uyumsuz bir çözüm için zaman uyumlu çözüm dönüştürmek için başlamak için en iyi yerdir GetURLContents çünkü çağrıları HttpWebRequest yöntemi GetResponse ve Stream yöntemi CopyTo olan web uygulama nerede erişir..net Framework dönüştürme her iki yöntem de zaman uyumsuz sürümlerini sağlayarak kolaylaştırır.
Kullanılan yöntemleri hakkında daha fazla bilgi için GetURLContents, bkz: WebRequest.
[!NOT]
Bu izlenecek yolda adımları birkaç derleyici hataları görüntülenir.Onları göz ardı ve izlenecek yol ile devam edebilirsiniz.
Üçüncü satırda adlı yöntemini değiştirme GetURLContents dan GetResponse için zaman uyumsuz, görev tabanlı GetResponseAsync yöntem.
Using response As WebResponse = webReq.GetResponseAsync()
using (WebResponse response = webReq.GetResponseAsync())
GetResponseAsyncdöndüren bir Task.Bu durumda, görev dönüş değişkeni, TResult, türüne sahip WebResponse.Gerçek bir üretmek için promise görevdir WebResponse istenen verileri karşıdan ve görevin tamamlanması için çalıştıktan sonra nesne.
Almak için WebResponse görevden değer, geçerli bir Await (Visual Basic için) veya bekler çağrısına işleci (C#) GetResponseAsync, aşağıdaki kodda gösterildiği gibi.
Using response As WebResponse = Await webReq.GetResponseAsync()
using (WebResponse response = await webReq.GetResponseAsync())
Await işleci geçerli yönteminin çalışmasını askıya alır GetURLContents, awaited görev tamamlanıncaya kadar.Bu arada, denetimi geçerli yöntemini çağırana döndürür.Bu örnekte, geçerli yöntemdir GetURLContents, ve arayan SumPageSizes.Görev bittiğinde, taahhüt edilen WebResponse nesnesi değişkenine atanan değeri awaited görev olarak üretilen ve response.
Bir önceki ifadenin ne olur açıklığa kavuşturmak için aşağıdaki iki ifadeyi ayrılabilir.
'Dim responseTask As Task(Of WebResponse) = webReq.GetResponseAsync() 'Using response As WebResponse = Await responseTask
//Task<WebResponse> responseTask = webReq.GetResponseAsync(); //using (WebResponse response = await responseTask)
The call to webReq.GetResponseAsync returns a Task(Of WebResponse) or Task<WebResponse>.Await işleci almak için göreve uygulanan sonra WebResponse değeri.
Zaman uyumsuz yönteminizi görevin tamamlanma bağımlı değildir yapmak için iş varsa, yöntem o iş için zaman uyumsuz yöntem ve await işleç uygulanmadan önce çağırdıktan sonra bu iki ifade arasında devam edebilirsiniz.Örnekler için, bkz. Nasıl yapılır: Async ve Await Kullanarak Birden Çok Web İsteğini Paralel Hale Getirme (C# ve Visual Basic) ve Nasıl yapılır: Task.WhenAll Kullanarak Zaman Uyumsuz İzlenecek Yolu Genişletme (C# ve Visual Basic).
Eklediğiniz çünkü Await veya await işleç önceki adımda bir derleyici hatası oluşur.İşleci ile işaretlenmiş yöntemler kullanılabilir zaman uyumsuz (Visual Basic için) veya zaman uyumsuz değiştirici (C#).Çağrısı değiştirmek için dönüştürme adımları yineleyin ancak hatayı göz ardı CopyTo bir çağrı ile CopyToAsync.
Değiştirmek için çağrılan yöntemin adı CopyToAsync.
CopyTo Veya CopyToAsync yöntemi, baðýmsýz deðiþken baytı kopyalar contentve anlamlı bir değer döndürmüyor.Zaman uyumlu sürümünde, çağrı CopyTo bir değer döndürmez basit açıklamadır.Zaman uyumsuz sürümü CopyToAsync, döndürür bir Task.Görev "Task(void)" gibi işlev görür ve beklediğin bir yöntem sağlar.Uygulama Await veya await çağrısına CopyToAsync, aşağıdaki kodda gösterildiği gibi.
Await responseStream.CopyToAsync(content)
await responseStream.CopyToAsync(content);
Önceki deyimi aşağıdaki iki kod satırı kısaltmasıdır.
' CopyToAsync returns a Task, not a Task<T>. 'Dim copyTask As Task = responseStream.CopyToAsync(content) ' When copyTask is completed, content contains a copy of ' responseStream. 'Await copyTask
// CopyToAsync returns a Task, not a Task<T>. //Task copyTask = responseStream.CopyToAsync(content); // When copyTask is completed, content contains a copy of // responseStream. //await copyTask;
Yapılması kalan tüm GetURLContents yöntem imzası ayarlamak için.Kullanabileceğiniz Await veya await ile işaretlenmiş yöntemler işleç zaman uyumsuz (Visual Basic) veya zaman uyumsuz değiştirici (C#).Ekleme yöntemi olarak işaretlemek için değiştirici bir zaman uyumsuz yöntem, aşağıdaki kodda gösterildiği gibi.
Private Async Function GetURLContents(url As String) As Byte()
private async byte[] GetURLContents(string url)
Zaman uyumsuz bir yöntemin dönüş türü yalnızca olabilir Task, Task, veya void C# [NULL]'ta.Visual Basic'te, bir yöntem olmalıdır bir Function dönen bir Task veya Task(Of T), ya da yöntem olmalıdır bir Sub.Genellikle, bir Sub yöntemi (Visual Basic'te) veya dönüş türü void (C#) kullanılan yalnızca zaman uyumsuz olay işleyicisinde, burada Sub veya void gereklidir.Diğer durumlarda, kullanmanız Task(T) tamamlanmış yöntem varsa, bir dönmek veya dönmek t değeri döndürür ifade yazın ve kullandığınız Task tamamlanmış yöntem anlamlı bir değer döndürmezse.Düşünebilirsiniz Task dönüş türü olarak "Task(void)" anlamına gelir.
Daha fazla bilgi için bkz. Zaman Uyumsuz Dönüş Türleri (C# ve Visual Basic).
Yöntem GetURLContents bir dönüş ifadesi vardır ve deyimi bir bayt dizisi döndürür.Bu nedenle, dönen zaman uyumsuz sürümü Task(T), t bir bayt dizisi olduğu türüdür.Yöntem imzası aşağıdaki değişiklikleri yapın:
Dönüş türü ile değiştirmek Task(Of Byte()) (Visual Basic için) veya Task<byte[]> (C#).
Kuralı olarak, zaman uyumsuz yöntemleri "Zaman uyumsuz," biten adlara sahip böylece yöntemi yeniden adlandırma GetURLContentsAsync.
Aşağıdaki kod bu değişiklikleri gösterir.
Private Async Function GetURLContentsAsync(url As String) As Task(Of Byte())
private async Task<byte[]> GetURLContentsAsync(string url)
Bu birkaç değişiklikle dönüştürme GetURLContents için zaman uyumsuz yöntemini tamamlanır.
Zaman uyumsuz bir yönteme SumPageSizes dönüştürmek için
İçin önceki yordamdaki adımları yineleyin SumPageSizes.İlk olarak, çağrı değiştirme GetURLContents zaman uyumsuz bir çağrı.
Dan çağrılan yöntemin adını değiştirme GetURLContents için GetURLContentsAsync, zaten yapmadıysanız.
Uygulama Await veya await görev, GetURLContentsAsync dizi değeri elde bayt döndürür.
Aşağıdaki kod bu değişiklikleri gösterir.
Dim urlContents As Byte() = Await GetURLContentsAsync(url)
byte[] urlContents = await GetURLContentsAsync(url);
Aşağıdaki iki kod satırı önceki atama kısaltmasıdır.
' GetURLContentsAsync returns a task. At completion, the task ' produces a byte array. 'Dim getContentsTask As Task(Of Byte()) = GetURLContentsAsync(url) 'Dim urlContents As Byte() = Await getContentsTask
// GetURLContentsAsync returns a Task<T>. At completion, the task // produces a byte array. //Task<byte[]> getContentsTask = GetURLContentsAsync(url); //byte[] urlContents = await getContentsTask;
Yöntemin İmzada aşağıdaki değişiklikleri yapın:
İşaretleme yöntemi ile Async veya async değiştirici.
"Zaman uyumsuz" yöntem adı ekleyin.
Hiçbir görev dönüş değişkeni, t, bu süresi yoktur çünkü SumPageSizesAsync t için bir değer döndürmüyor(Hayır yöntemi olan Return veya return ifadesi.) Ancak, yöntem döndürmelidir bir Task awaitable olacak.Bu nedenle, aşağıdaki değişikliklerden birini yapın:
Visual Basic'te, değiştirme yöntemi türünden Sub için Function.İşlevin dönüş türü Task.
C# [NULL]'ta yöntemin dönüş türü değiştirme void için Task.
Aşağıdaki kod bu değişiklikleri gösterir.
Private Async Function SumPageSizesAsync() As Task
private async Task SumPageSizesAsync()
Dönüştürme işlemi SumPageSizes için SumPageSizesAsync tamamlandı.
Zaman uyumsuz bir yönteme startButton_Click dönüştürmek için
Olay işleyicisinde, çağrılan yöntemin adını değiştirme SumPageSizes için SumPageSizesAsync, zaten yapmadıysanız.
Çünkü SumPageSizesAsync bir zaman uyumsuz yöntem sonucu beklemek için olay işleyicisi kodu değiştirin.
Çağrı SumPageSizesAsync çağrısı yansıtan CopyToAsync , GetURLContentsAsync.Çağrı döndürür bir Taskdeğil, bir Task(T).
Önceki yordamlardan olduğu gibi bir ifade veya iki ifade kullanarak arama dönüştürebilirsiniz.Aşağıdaki kod bu değişiklikleri gösterir.
'' One-step async call. Await SumPageSizesAsync() ' Two-step async call. 'Dim sumTask As Task = SumPageSizesAsync() 'Await sumTask
// One-step async call. await SumPageSizesAsync(); // Two-step async call. //Task sumTask = SumPageSizesAsync(); //await sumTask;
Yanlışlıkla Project'e işlemi önlemek için üst kısmına aşağıdaki ifadeyi ekleyin startButton_Click devre dışı bırakmak için Start düğmesi.
' Disable the button until the operation is complete. startButton.IsEnabled = False
// Disable the button until the operation is complete. startButton.IsEnabled = false;
Düğmeye olay işleyicisi sonunda yeniden etkinleştirebilirsiniz.
' Reenable the button in case you want to run the operation again. startButton.IsEnabled = True
// Reenable the button in case you want to run the operation again. startButton.IsEnabled = true;
Yeniden giriş hakkında daha fazla bilgi için bkz: Zaman Uyumsuz Uygulamalarda Yeniden Girişi İşleme (C# ve Visual Basic).
Son olarak eklemek Async veya async değiştirici bildirimi için olay işleyicisi beklemek böylece SumPagSizesAsync.
Async Sub startButton_Click(sender As Object, e As RoutedEventArgs) Handles startButton.Click
private async void startButton_Click(object sender, RoutedEventArgs e)
Olay işleyicilerinin adları genellikle değiştirilmez.Dönüş türü için değiştirilmez Task olay işleyicileri dönüştürüldüğünden void C# [NULL]'ta ya da Sub Visual Basic'teki yordamlar.Bu nedenle, dönüş türü için Task.
Proje için zaman uyumsuz eşzamanlı işlem yapamayan dönüştürme işlemi tamamlandığında.
Zaman uyumsuz çözümü test etmek için
Seçim programını çalıştırın ve sonra seçmek için F5 tuşuna Start düğmesi.
Eşzamanlı çözümde çıktı benzer bir çıktı görüntülenir.Ancak, aşağıdaki farkları dikkat edin.
Sonuçları işlemi tamamlandıktan sonra aynı zamanda oluşmaz.Örneğin, her iki program bir satırında startButton_Click , metin kutusunu temizler.İsterseniz çalışmaları arasında metin kutusunu temizlemek için hedefi olan Başlat ikinci kez bir dizi sonucu göründükten sonra düğme.Yalnızca sayıları ne zaman karşıdan yükleme tamamlandı ve UI iş parçacığı diğer iş yapmak ücretsiz ikinci kez görünmeden önce zaman uyumlu bir sürümünü, metin kutusu temizlenir.Seçtiğiniz hemen sonra zaman uyumsuz sürümde metin kutusunu temizler Start düğmesi.
En önemlisi, UI iş parçacığı, karşıdan yükleme sırasında kilitli değilse.Taşımak veya web kaynakları karşıdan yüklenirken, pencereyi yeniden boyutlandırmak sayılan ve görüntülenir.Yanıt vermeyen işlemi seçerek iptal veya Web sitelerinin biri ise yavaş Kapat düğmesi (sağ üst köşesinde kırmızı alanında x).
.net Framework yöntemi ile GetURLContentsAsync yöntemini değiştirmek için
.net Framework 4.5 kullanabileceğiniz birçok zaman uyumsuz yöntem sağlar.Bunlardan biri, HttpClient yöntemi GetByteArrayAsync(String), yalnızca bu örnek için gerekenleri yapar.Bunu yerine GetURLContentsAsync bir önceki yordamda oluşturduğunuz yöntemi.
İlk adım oluşturmaktır bir HttpClient yöntemi nesne SumPageSizesAsync.Yöntem başlangıcında aşağıdaki bildiriyi ekleyin.
' Declare an HttpClient object and increase the buffer size. The ' default buffer size is 65,536. Dim client As HttpClient = New HttpClient() With {.MaxResponseContentBufferSize = 1000000}
// Declare an HttpClient object and increase the buffer size. The // default buffer size is 65,536. HttpClient client = new HttpClient() { MaxResponseContentBufferSize = 1000000 };
İçinde SumPageSizesAsync, çağrısı yerine kendi GetURLContentsAsync yöntemine yapılan bir çağrıyla HttpClient yöntem.
Dim urlContents As Byte() = Await client.GetByteArrayAsync(url)
byte[] urlContents = await client.GetByteArrayAsync(url);
Kaldırma veya yorum GetURLContentsAsync yazdığınız yöntemi.
Seçim programını çalıştırın ve sonra seçmek için F5 tuşuna Start düğmesi.
Project'in bu sürümü, davranışını, "zaman uyumsuz çözümü test etmek için" yordamı açıklar davranışını eşleşen ancak bile sizden daha az çaba ile.
Örnek
Zaman uyumsuz kullanarak zaman uyumsuz bir çözüm arasında bir zaman uyumlu dönüştürme tam örneği aşağıdaki kodu içeren GetURLContentsAsync yazdığınız yöntemi.Bunu kesinlikle özgün, zaman uyumlu çözüm benzer dikkat edin.
' Add the following Imports statements, and add a reference for System.Net.Http.
Imports System.Net.Http
Imports System.Net
Imports System.IO
Class MainWindow
Async Sub startButton_Click(sender As Object, e As RoutedEventArgs) Handles startButton.Click
' Disable the button until the operation is complete.
startButton.IsEnabled = False
resultsTextBox.Clear()
'' One-step async call.
Await SumPageSizesAsync()
' Two-step async call.
'Dim sumTask As Task = SumPageSizesAsync()
'Await sumTask
resultsTextBox.Text &= vbCrLf & "Control returned to button1_Click."
' Reenable the button in case you want to run the operation again.
startButton.IsEnabled = True
End Sub
Private Async Function SumPageSizesAsync() As Task
' Make a list of web addresses.
Dim urlList As List(Of String) = SetUpURLList()
Dim total = 0
For Each url In urlList
Dim urlContents As Byte() = Await GetURLContentsAsync(url)
' The previous line abbreviates the following two assignment statements.
' GetURLContentsAsync returns a task. At completion, the task
' produces a byte array.
'Dim getContentsTask As Task(Of Byte()) = GetURLContentsAsync(url)
'Dim urlContents As Byte() = Await getContentsTask
DisplayResults(url, urlContents)
' Update the total.
total += urlContents.Length
Next
' Display the total count for all of the websites.
resultsTextBox.Text &= String.Format(vbCrLf & vbCrLf &
"Total bytes returned: {0}" & vbCrLf, total)
End Function
Private Function SetUpURLList() As List(Of String)
Dim urls = New List(Of String) From
{
"https://msdn.microsoft.com/library/windows/apps/br211380.aspx",
"https://msdn.microsoft.com",
"https://msdn.microsoft.com/en-us/library/hh290136.aspx",
"https://msdn.microsoft.com/en-us/library/ee256749.aspx",
"https://msdn.microsoft.com/en-us/library/hh290138.aspx",
"https://msdn.microsoft.com/en-us/library/hh290140.aspx",
"https://msdn.microsoft.com/en-us/library/dd470362.aspx",
"https://msdn.microsoft.com/en-us/library/aa578028.aspx",
"https://msdn.microsoft.com/en-us/library/ms404677.aspx",
"https://msdn.microsoft.com/en-us/library/ff730837.aspx"
}
Return urls
End Function
Private Async Function GetURLContentsAsync(url As String) As Task(Of Byte())
' The downloaded resource ends up in the variable named content.
Dim content = New MemoryStream()
' Initialize an HttpWebRequest for the current URL.
Dim webReq = CType(WebRequest.Create(url), HttpWebRequest)
' Send the request to the Internet resource and wait for
' the response.
Using response As WebResponse = Await webReq.GetResponseAsync()
' The previous statement abbreviates the following two statements.
'Dim responseTask As Task(Of WebResponse) = webReq.GetResponseAsync()
'Using response As WebResponse = Await responseTask
' Get the data stream that is associated with the specified URL.
Using responseStream As Stream = response.GetResponseStream()
' Read the bytes in responseStream and copy them to content.
Await responseStream.CopyToAsync(content)
' The previous statement abbreviates the following two statements.
' CopyToAsync returns a Task, not a Task<T>.
'Dim copyTask As Task = responseStream.CopyToAsync(content)
' When copyTask is completed, content contains a copy of
' responseStream.
'Await copyTask
End Using
End Using
' Return the result as a byte array.
Return content.ToArray()
End Function
Private Sub DisplayResults(url As String, content As Byte())
' Display the length of each website. The string format
' is designed to be used with a monospaced font, such as
' Lucida Console or Global Monospace.
Dim bytes = content.Length
' Strip off the "http://".
Dim displayURL = url.Replace("http://", "")
resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes)
End Sub
End Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
// Add the following using directives, and add a reference for System.Net.Http.
using System.Net.Http;
using System.IO;
using System.Net;
namespace AsyncExampleWPF
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private async void startButton_Click(object sender, RoutedEventArgs e)
{
// Disable the button until the operation is complete.
startButton.IsEnabled = false;
resultsTextBox.Clear();
// One-step async call.
await SumPageSizesAsync();
// Two-step async call.
//Task sumTask = SumPageSizesAsync();
//await sumTask;
resultsTextBox.Text += "\r\nControl returned to startButton_Click.\r\n";
// Reenable the button in case you want to run the operation again.
startButton.IsEnabled = true;
}
private async Task SumPageSizesAsync()
{
// Make a list of web addresses.
List<string> urlList = SetUpURLList();
var total = 0;
foreach (var url in urlList)
{
byte[] urlContents = await GetURLContentsAsync(url);
// The previous line abbreviates the following two assignment statements.
// GetURLContentsAsync returns a Task<T>. At completion, the task
// produces a byte array.
//Task<byte[]> getContentsTask = GetURLContentsAsync(url);
//byte[] urlContents = await getContentsTask;
DisplayResults(url, urlContents);
// Update the total.
total += urlContents.Length;
}
// Display the total count for all of the websites.
resultsTextBox.Text +=
string.Format("\r\n\r\nTotal bytes returned: {0}\r\n", total);
}
private List<string> SetUpURLList()
{
List<string> urls = new List<string>
{
"https://msdn.microsoft.com/library/windows/apps/br211380.aspx",
"https://msdn.microsoft.com",
"https://msdn.microsoft.com/en-us/library/hh290136.aspx",
"https://msdn.microsoft.com/en-us/library/ee256749.aspx",
"https://msdn.microsoft.com/en-us/library/hh290138.aspx",
"https://msdn.microsoft.com/en-us/library/hh290140.aspx",
"https://msdn.microsoft.com/en-us/library/dd470362.aspx",
"https://msdn.microsoft.com/en-us/library/aa578028.aspx",
"https://msdn.microsoft.com/en-us/library/ms404677.aspx",
"https://msdn.microsoft.com/en-us/library/ff730837.aspx"
};
return urls;
}
private async Task<byte[]> GetURLContentsAsync(string url)
{
// The downloaded resource ends up in the variable named content.
var content = new MemoryStream();
// Initialize an HttpWebRequest for the current URL.
var webReq = (HttpWebRequest)WebRequest.Create(url);
// Send the request to the Internet resource and wait for
// the response.
using (WebResponse response = await webReq.GetResponseAsync())
// The previous statement abbreviates the following two statements.
//Task<WebResponse> responseTask = webReq.GetResponseAsync();
//using (WebResponse response = await responseTask)
{
// Get the data stream that is associated with the specified url.
using (Stream responseStream = response.GetResponseStream())
{
// Read the bytes in responseStream and copy them to content.
await responseStream.CopyToAsync(content);
// The previous statement abbreviates the following two statements.
// CopyToAsync returns a Task, not a Task<T>.
//Task copyTask = responseStream.CopyToAsync(content);
// When copyTask is completed, content contains a copy of
// responseStream.
//await copyTask;
}
}
// Return the result as a byte array.
return content.ToArray();
}
private void DisplayResults(string url, byte[] content)
{
// Display the length of each website. The string format
// is designed to be used with a monospaced font, such as
// Lucida Console or Global Monospace.
var bytes = content.Length;
// Strip off the "http://".
var displayURL = url.Replace("http://", "");
resultsTextBox.Text += string.Format("\n{0,-58} {1,8}", displayURL, bytes);
}
}
}
Aşağıdaki kodu kullanan çözüm tam örneği içerir HttpClient yöntemi, GetByteArrayAsync.
' Add the following Imports statements, and add a reference for System.Net.Http.
Imports System.Net.Http
Imports System.Net
Imports System.IO
Class MainWindow
Async Sub startButton_Click(sender As Object, e As RoutedEventArgs) Handles startButton.Click
resultsTextBox.Clear()
' Disable the button until the operation is complete.
startButton.IsEnabled = False
' One-step async call.
Await SumPageSizesAsync()
'' Two-step async call.
'Dim sumTask As Task = SumPageSizesAsync()
'Await sumTask
resultsTextBox.Text &= vbCrLf & "Control returned to button1_Click."
' Reenable the button in case you want to run the operation again.
startButton.IsEnabled = True
End Sub
Private Async Function SumPageSizesAsync() As Task
' Declare an HttpClient object and increase the buffer size. The
' default buffer size is 65,536.
Dim client As HttpClient =
New HttpClient() With {.MaxResponseContentBufferSize = 1000000}
' Make a list of web addresses.
Dim urlList As List(Of String) = SetUpURLList()
Dim total = 0
For Each url In urlList
' GetByteArrayAsync returns a task. At completion, the task
' produces a byte array.
Dim urlContents As Byte() = Await client.GetByteArrayAsync(url)
' The following two lines can replace the previous assignment statement.
'Dim getContentsTask As Task(Of Byte()) = client.GetByteArrayAsync(url)
'Dim urlContents As Byte() = Await getContentsTask
DisplayResults(url, urlContents)
' Update the total.
total += urlContents.Length
Next
' Display the total count for all of the websites.
resultsTextBox.Text &= String.Format(vbCrLf & vbCrLf &
"Total bytes returned: {0}" & vbCrLf, total)
End Function
Private Function SetUpURLList() As List(Of String)
Dim urls = New List(Of String) From
{
"https://msdn.microsoft.com/library/windows/apps/br211380.aspx",
"https://msdn.microsoft.com",
"https://msdn.microsoft.com/en-us/library/hh290136.aspx",
"https://msdn.microsoft.com/en-us/library/ee256749.aspx",
"https://msdn.microsoft.com/en-us/library/hh290138.aspx",
"https://msdn.microsoft.com/en-us/library/hh290140.aspx",
"https://msdn.microsoft.com/en-us/library/dd470362.aspx",
"https://msdn.microsoft.com/en-us/library/aa578028.aspx",
"https://msdn.microsoft.com/en-us/library/ms404677.aspx",
"https://msdn.microsoft.com/en-us/library/ff730837.aspx"
}
Return urls
End Function
Private Sub DisplayResults(url As String, content As Byte())
' Display the length of each website. The string format
' is designed to be used with a monospaced font, such as
' Lucida Console or Global Monospace.
Dim bytes = content.Length
' Strip off the "http://".
Dim displayURL = url.Replace("http://", "")
resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes)
End Sub
End Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
// Add the following using directives, and add a reference for System.Net.Http.
using System.Net.Http;
using System.IO;
using System.Net;
namespace AsyncExampleWPF
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private async void startButton_Click(object sender, RoutedEventArgs e)
{
resultsTextBox.Clear();
// Disable the button until the operation is complete.
startButton.IsEnabled = false;
// One-step async call.
await SumPageSizesAsync();
//// Two-step async call.
//Task sumTask = SumPageSizesAsync();
//await sumTask;
resultsTextBox.Text += "\r\nControl returned to startButton_Click.\r\n";
// Reenable the button in case you want to run the operation again.
startButton.IsEnabled = true;
}
private async Task SumPageSizesAsync()
{
// Declare an HttpClient object and increase the buffer size. The
// default buffer size is 65,536.
HttpClient client =
new HttpClient() { MaxResponseContentBufferSize = 1000000 };
// Make a list of web addresses.
List<string> urlList = SetUpURLList();
var total = 0;
foreach (var url in urlList)
{
// GetByteArrayAsync returns a task. At completion, the task
// produces a byte array.
byte[] urlContents = await client.GetByteArrayAsync(url);
// The following two lines can replace the previous assignment statement.
//Task<byte[]> getContentsTask = client.GetByteArrayAsync(url);
//byte[] urlContents = await getContentsTask;
DisplayResults(url, urlContents);
// Update the total.
total += urlContents.Length;
}
// Display the total count for all of the websites.
resultsTextBox.Text +=
string.Format("\r\n\r\nTotal bytes returned: {0}\r\n", total);
}
private List<string> SetUpURLList()
{
List<string> urls = new List<string>
{
"https://msdn.microsoft.com/library/windows/apps/br211380.aspx",
"https://msdn.microsoft.com",
"https://msdn.microsoft.com/en-us/library/hh290136.aspx",
"https://msdn.microsoft.com/en-us/library/ee256749.aspx",
"https://msdn.microsoft.com/en-us/library/hh290138.aspx",
"https://msdn.microsoft.com/en-us/library/hh290140.aspx",
"https://msdn.microsoft.com/en-us/library/dd470362.aspx",
"https://msdn.microsoft.com/en-us/library/aa578028.aspx",
"https://msdn.microsoft.com/en-us/library/ms404677.aspx",
"https://msdn.microsoft.com/en-us/library/ff730837.aspx"
};
return urls;
}
private void DisplayResults(string url, byte[] content)
{
// Display the length of each website. The string format
// is designed to be used with a monospaced font, such as
// Lucida Console or Global Monospace.
var bytes = content.Length;
// Strip off the "http://".
var displayURL = url.Replace("http://", "");
resultsTextBox.Text += string.Format("\n{0,-58} {1,8}", displayURL, bytes);
}
}
}
Ayrıca bkz.
Görevler
Nasıl yapılır: Task.WhenAll Kullanarak Zaman Uyumsuz İzlenecek Yolu Genişletme (C# ve Visual Basic)
İzlenecek Yol: Hata Ayıklayıcıyı Zaman Uyumsuz Yöntemlerle Kullanma
Başvuru
Kavramlar
Async ve Await ile Zaman Uyumsuz Programlama (C# ve Visual Basic)
Zaman Uyumsuz Dönüş Türleri (C# ve Visual Basic)
Dosya Erişimi için Async Kullanma (C# ve Visual Basic)
Diğer Kaynaklar
Zaman uyumsuz örnek: erişen Web gözden geçirme (C# ve Visual Basic)
Görev tabanlı zaman uyumsuz programlama (DOKUNUN)
Quickstart: await işlecini kullanarak zaman uyumsuz programlama için