Aracılığıyla paylaş


Bir Görev Tamamlandıktan Sonra Geri Kalan Görevleri İptal Etme (C# ve Visual Basic)

Kullanarak Task.WhenAny yöntemi ile birlikte bir CancellationToken, bir görev tamamlandığında, kalan tüm görevleri iptal edebilirsiniz.WhenAny Yöntemi görevler topluluğudur bir bağımsız değişken alır.Yöntem tüm görevleri başlatır ve tek bir görev verir.Koleksiyondaki herhangi bir görev tamamlandığında, tek bir görev tamamlanmıştır.

Bu örnek iptali belirteci ile birlikte kullanımı gösterilmiştir WhenAny ilk görev görevler koleksiyonundan tamamlanması ve kalan görevleri iptal etmek için tutacak.Her görev bir Web sitesinin içeriği karşıdan yükler.Örnek tamamlamak için ilk yükleme içeriğini uzunluğunu görüntüler ve diğer yüklemeleri iptal eder.

[!NOT]

Örnekleri çalıştırmak için Visual Studio 2012 sahip Visual Studio Express 2012 için Windows Masaüstü, veya bilgisayarınızda yüklü .NET Framework 4.5.

Örnek yükleme

Tam Windows Presentation Foundation (wpf) projeden indirebilirsiniz zaman uyumsuz örnek: ince ayar uygulamanız ve sonra aşağıdaki adımları izleyin.

  1. Karşıdan yüklenen ve başlatın dosyasını indirip sıkıştırmasını açın Visual Studio 2012.

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

  3. İçinde Açık projeniz iletişim kutusunda, kopyalanırken açılır örnek kodu içeren klasörü açın ve sonra AsyncFineTuningCS veya AsyncFineTuningVB için çözüm (.sln) dosyasını açın.

  4. İçinde Çözüm Gezgini, kısayol menüsünü açmak CancelAfterOneTask 'ı seçin ve proje başlangıç projesi olarak ayarla.

  5. F5 tuşuna basarak projeyi çalıştırın seçin.

    Projenin hata ayıklama olmadan çalıştırmak için Ctrl + F5 tuşları seçin.

  6. Program birkaç kez farklı yüklemeler ilk bitiş doğrulamak için çalıştırın.

Proje karşıdan yüklemek istemiyorsanız, bu konunun sonundaki MainWindow.xaml.vb ve MainWindow.xaml.cs dosyalarını gözden geçirebilirsiniz.

Örnek oluşturma

Bu konudaki örnek olarak geliştirilen projeye ekler Bir Görevi veya Görev Listesini İptal Etme (C# ve Visual Basic) görev listesini iptal etmek.Rağmen aynı kullanıcı Arabirimi örnek kullanır İptal düğmesini değil açıkça kullanılan.

Örnek oluşturmak için kendiniz step by step "Örnek karşıdan yükleme" bölümündeki yönergeleri izleyin, ancak seçim CancelAListOfTasks olarak Başlangıç projesi.Bu konudaki değişiklikleri bu projeye ekleyin.

Dosyasındaki MainWindow.xaml.vb veya MainWindow.xaml.cs CancelAListOfTasks proje, her Web sitesi için işleme adımlarını döngüde tarafından taşınan geçişi başlatma AccessTheWebAsync için aşağıdaki zaman uyumsuz yöntem.

' ***Bundle the processing steps for a website into one async method.
Async Function ProcessURLAsync(url As String, client As HttpClient, ct As CancellationToken) As Task(Of Integer)

    ' GetAsync returns a Task(Of HttpResponseMessage). 
    Dim response As HttpResponseMessage = Await client.GetAsync(url, ct)

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

    Return urlContents.Length
End Function
// ***Bundle the processing steps for a website into one async method.
async Task<int> ProcessURLAsync(string url, HttpClient client, CancellationToken ct)
{
    // GetAsync returns a Task<HttpResponseMessage>. 
    HttpResponseMessage response = await client.GetAsync(url, ct);

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

    return urlContents.Length;
}

İçinde AccessTheWebAsync, bu örnek, bir sorgu kullanır ToArray<TSource> yöntemi ve WhenAny oluşturmak ve görevler dizisi başlatmak için yöntem.Uygulama WhenAny diziye tek bir görev, beklediğin döner görevlerin tamamlanma dizideki ulaşmak için ilk görev olarak değerlendirilir.

Aşağıdaki değişiklikleri AccessTheWebAsync.Yıldız kod dosyasında değişiklikler işaretleyin.

  1. Yorum veya döngü silin.

  2. Bir sorgu yürütüldüğünde, oluşturmakta genel görevlerin bir koleksiyon oluşturur.Her çağrı ProcessURLAsync döndüren bir Task<TResult> burada TResult bir tamsayıdır.

    ' ***Create a query that, when executed, returns a collection of tasks.
    Dim downloadTasksQuery As IEnumerable(Of Task(Of Integer)) =
        From url In urlList Select ProcessURLAsync(url, client, ct)
    
    // ***Create a query that, when executed, returns a collection of tasks.
    IEnumerable<Task<int>> downloadTasksQuery =
        from url in urlList select ProcessURLAsync(url, client, ct);
    
  3. Call ToArray görevleri başlatmak ve sorguyu yürütmek için.Uygulama WhenAny yöntemi bir sonraki adımda ve sorguyu yürütmek görevleri başlatmak ToArray, ancak diğer yöntemleri görünmeyebilir.Sorgu yürütme açıkça zorlamak için en güvenli yöntem olacaktır.

    ' ***Use ToArray to execute the query and start the download tasks. 
    Dim downloadTasks As Task(Of Integer)() = downloadTasksQuery.ToArray()
    
    // ***Use ToArray to execute the query and start the download tasks. 
    Task<int>[] downloadTasks = downloadTasksQuery.ToArray();
    
  4. Call WhenAny üzerinde görevler topluluğudur.WhenAnyreturns a Task(Of Task(Of Integer)) or Task<Task<int>>.Yani, WhenAny değerlendiren bir görev döndüren tek bir Task(Of Integer) veya Task<int> zaman beklediğin.Tek bu görevi tamamlamak için koleksiyondaki ilk görevdir.Bitti ilk görevin atandığı firstFinishedTask.Türü firstFinishedTask olan Task<TResult> burada TResult , dönüş türü tamsayı olduğundan ProcessURLAsync.

    ' ***Call WhenAny and then await the result. The task that finishes 
    ' first is assigned to firstFinishedTask.
    Dim firstFinishedTask As Task(Of Integer) = Await Task.WhenAny(downloadTasks)
    
    // ***Call WhenAny and then await the result. The task that finishes 
    // first is assigned to firstFinishedTask.
    Task<int> firstFinishedTask = await Task.WhenAny(downloadTasks);
    
  5. Bu örnekte, yalnızca ilk bittikten görev içinde ilgi duyduğunuz.Bu nedenle, CancellationTokenSource.Cancel kalan görevleri iptal etmek için.

    ' ***Cancel the rest of the downloads. You just want the first one.
    cts.Cancel()
    
    // ***Cancel the rest of the downloads. You just want the first one.
    cts.Cancel();
    
  6. Son olarak, beklemek firstFinishedTask yüklenen içerik uzunluğu almak için.

    Dim length = Await firstFinishedTask
    resultsTextBox.Text &= String.Format(vbCrLf & "Length of the downloaded website:  {0}" & vbCrLf, length)
    
    var length = await firstFinishedTask;
    resultsTextBox.Text += String.Format("\r\nLength of the downloaded website:  {0}\r\n", length);
    

Program birkaç kez farklı yüklemeler ilk bitiş doğrulamak için çalıştırın.

Tam Örnek

Aşağıdaki kod tam MainWindow.xaml.vb veya MainWindow.xaml.cs örneğin dosyasıdır.Yıldız, bu örnek için eklenmiş öğeleri işaretleyin.

İçin bir başvuru eklemelisiniz dikkat edin System.Net.Http.

Projeden indirebilirsiniz zaman uyumsuz örnek: ince ayar uygulamanız.

' Add an Imports directive and a reference for System.Net.Http.
Imports System.Net.Http

' Add the following Imports directive for System.Threading.
Imports System.Threading

Class MainWindow

    ' Declare a System.Threading.CancellationTokenSource.
    Dim cts As CancellationTokenSource


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

        ' Instantiate the CancellationTokenSource.
        cts = New CancellationTokenSource()

        resultsTextBox.Clear()

        Try
            Await AccessTheWebAsync(cts.Token)
            resultsTextBox.Text &= vbCrLf & "Download complete."

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

        Catch ex As Exception
            resultsTextBox.Text &= vbCrLf & "Download failed." & vbCrLf
        End Try

        ' Set the CancellationTokenSource to Nothing when the download is complete.
        cts = Nothing
    End Sub


    ' You can still include a Cancel button if you want to.
    Private Sub cancelButton_Click(sender As Object, e As RoutedEventArgs)

        If cts IsNot Nothing Then
            cts.Cancel()
        End If
    End Sub


    ' Provide a parameter for the CancellationToken.
    ' Change the return type to Task because the method has no return statement.
    Async Function AccessTheWebAsync(ct As CancellationToken) As Task

        Dim client As HttpClient = New HttpClient()

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

        '' Comment out or delete the loop.
        ''For Each url In urlList
        ''    ' GetAsync returns a Task(Of HttpResponseMessage). 
        ''    ' Argument ct carries the message if the Cancel button is chosen. 
        ''    ' Note that the Cancel button can cancel all remaining downloads.
        ''    Dim response As HttpResponseMessage = Await client.GetAsync(url, ct)

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

        ''    resultsTextBox.Text &=
        ''        String.Format(vbCrLf & "Length of the downloaded string: {0}." & vbCrLf, urlContents.Length)
        ''Next

        ' ***Create a query that, when executed, returns a collection of tasks.
        Dim downloadTasksQuery As IEnumerable(Of Task(Of Integer)) =
            From url In urlList Select ProcessURLAsync(url, client, ct)

        ' ***Use ToArray to execute the query and start the download tasks. 
        Dim downloadTasks As Task(Of Integer)() = downloadTasksQuery.ToArray()

        ' ***Call WhenAny and then await the result. The task that finishes 
        ' first is assigned to firstFinishedTask.
        Dim firstFinishedTask As Task(Of Integer) = Await Task.WhenAny(downloadTasks)

        ' ***Cancel the rest of the downloads. You just want the first one.
        cts.Cancel()

        ' ***Await the first completed task and display the results
        ' Run the program several times to demonstrate that different
        ' websites can finish first.
        Dim length = Await firstFinishedTask
        resultsTextBox.Text &= String.Format(vbCrLf & "Length of the downloaded website:  {0}" & vbCrLf, length)
    End Function


    ' ***Bundle the processing steps for a website into one async method.
    Async Function ProcessURLAsync(url As String, client As HttpClient, ct As CancellationToken) As Task(Of Integer)

        ' GetAsync returns a Task(Of HttpResponseMessage). 
        Dim response As HttpResponseMessage = Await client.GetAsync(url, ct)

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

        Return urlContents.Length
    End Function


    ' Add a method that creates a list of web addresses.
    Private Function SetUpURLList() As List(Of String)

        Dim urls = New List(Of String) From
            {
                "https://msdn.microsoft.com",
                "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

End Class


' Sample output:

' Length of the downloaded website:  158856

' Download complete.
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;

// Add the following using directive.
using System.Threading;

namespace CancelAfterOneTask
{
    public partial class MainWindow : Window
    {
        // Declare a System.Threading.CancellationTokenSource.
        CancellationTokenSource cts;

        public MainWindow()
        {
            InitializeComponent();
        }


        private async void startButton_Click(object sender, RoutedEventArgs e)
        {
            // Instantiate the CancellationTokenSource.
            cts = new CancellationTokenSource();

            resultsTextBox.Clear();

            try
            {
                await AccessTheWebAsync(cts.Token);
                resultsTextBox.Text += "\r\nDownload complete.";
            }
            catch (OperationCanceledException)
            {
                resultsTextBox.Text += "\r\nDownload canceled.";
            }
            catch (Exception)
            {
                resultsTextBox.Text += "\r\nDownload failed.";
            }

            // Set the CancellationTokenSource to null when the download is complete.
            cts = null;
        }


        // You can still include a Cancel button if you want to.
        private void cancelButton_Click(object sender, RoutedEventArgs e)
        {
            if (cts != null)
            {
                cts.Cancel();
            }
        }


        // Provide a parameter for the CancellationToken.
        async Task AccessTheWebAsync(CancellationToken ct)
        {
            HttpClient client = new HttpClient();

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

            // ***Comment out or delete the loop.
            //foreach (var url in urlList)
            //{
            //    // GetAsync returns a Task<HttpResponseMessage>. 
            //    // Argument ct carries the message if the Cancel button is chosen. 
            //    // ***Note that the Cancel button can cancel all remaining downloads.
            //    HttpResponseMessage response = await client.GetAsync(url, ct);

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

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

            // ***Create a query that, when executed, returns a collection of tasks.
            IEnumerable<Task<int>> downloadTasksQuery =
                from url in urlList select ProcessURLAsync(url, client, ct);

            // ***Use ToArray to execute the query and start the download tasks. 
            Task<int>[] downloadTasks = downloadTasksQuery.ToArray();

            // ***Call WhenAny and then await the result. The task that finishes 
            // first is assigned to firstFinishedTask.
            Task<int> firstFinishedTask = await Task.WhenAny(downloadTasks);

            // ***Cancel the rest of the downloads. You just want the first one.
            cts.Cancel();

            // ***Await the first completed task and display the results. 
            // Run the program several times to demonstrate that different
            // websites can finish first.
            var length = await firstFinishedTask;
            resultsTextBox.Text += String.Format("\r\nLength of the downloaded website:  {0}\r\n", length);
        }


        // ***Bundle the processing steps for a website into one async method.
        async Task<int> ProcessURLAsync(string url, HttpClient client, CancellationToken ct)
        {
            // GetAsync returns a Task<HttpResponseMessage>. 
            HttpResponseMessage response = await client.GetAsync(url, ct);

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

            return urlContents.Length;
        }


        // Add a method that creates a list of web addresses.
        private List<string> SetUpURLList()
        {
            List<string> urls = new List<string> 
            { 
                "https://msdn.microsoft.com",
                "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;
        }
    }
    // Sample output:

    // Length of the downloaded website:  158856

    // Download complete.
}

Ayrıca bkz.

Başvuru

WhenAny

Kavramlar

Async Uygulamanızda Hassas Ayar Yapma (C# ve Visual Basic)

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

Diğer Kaynaklar

Zaman uyumsuz örnek: İnce uygulamanızı Tuning