Görev iptali

System.Threading.Tasks.Task ve System.Threading.Tasks.Task<TResult> sınıfları, iptal belirteçleri kullanarak iptali destekler. Daha fazla bilgi için bkz . Yönetilen İş Parçacıklarında İptal. Görev sınıflarında iptal işlemi, iptal edilebilir bir işlemi temsil eden kullanıcı temsilcisi ile iptali isteyen kod arasında işbirliği içerir. Başarılı bir iptal işlemi, istekte bulunan kodun yöntemini çağırmasını CancellationTokenSource.Cancel ve kullanıcı temsilcisinin işlemi zamanında sonlandırmasını içerir. Aşağıdaki seçeneklerden birini kullanarak işlemi sonlandırabilirsiniz:

  • Temsilciden geri dönerek. Birçok senaryoda bu seçenek yeterlidir. Ancak, bu şekilde iptal edilen bir görev örneği duruma değil TaskStatus.Canceled duruma geçirilirTaskStatus.RanToCompletion.

  • bir OperationCanceledException oluşturup iptalin istendiği belirteci geçirerek. Gerçekleştirmenin tercih edilen yolu yöntemini kullanmaktır ThrowIfCancellationRequested . Bu şekilde iptal edilen bir görev İptal Edildi durumuna geçirilir ve bu durum, çağıran kodun görevin iptal isteğine yanıt verdiğini doğrulamak için kullanabileceği bir görevdir.

Aşağıdaki örnek, özel durum oluşturan görev iptali için temel deseni gösterir:

Not

Belirteç, kullanıcı temsilcisine ve görev örneğine geçirilir.

using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        var tokenSource2 = new CancellationTokenSource();
        CancellationToken ct = tokenSource2.Token;

        var task = Task.Run(() =>
        {
            // Were we already canceled?
            ct.ThrowIfCancellationRequested();

            bool moreToDo = true;
            while (moreToDo)
            {
                // Poll on this property if you have to do
                // other cleanup before throwing.
                if (ct.IsCancellationRequested)
                {
                    // Clean up here, then...
                    ct.ThrowIfCancellationRequested();
                }
            }
        }, tokenSource2.Token); // Pass same token to Task.Run.

        tokenSource2.Cancel();

        // Just continue on this thread, or await with try-catch:
        try
        {
            await task;
        }
        catch (OperationCanceledException e)
        {
            Console.WriteLine($"{nameof(OperationCanceledException)} thrown with message: {e.Message}");
        }
        finally
        {
            tokenSource2.Dispose();
        }

        Console.ReadKey();
    }
}
Imports System.Threading
Imports System.Threading.Tasks

Module Test
    Sub Main()
        Dim tokenSource2 As New CancellationTokenSource()
        Dim ct As CancellationToken = tokenSource2.Token

        Dim t2 = Task.Factory.StartNew(Sub()
                                           ' Were we already canceled?
                                           ct.ThrowIfCancellationRequested()

                                           Dim moreToDo As Boolean = True
                                           While moreToDo = True
                                               ' Poll on this property if you have to do
                                               ' other cleanup before throwing.
                                               If ct.IsCancellationRequested Then

                                                   ' Clean up here, then...
                                                   ct.ThrowIfCancellationRequested()
                                               End If

                                           End While
                                       End Sub _
        , tokenSource2.Token) ' Pass same token to StartNew.

        ' Cancel the task.
        tokenSource2.Cancel()

        ' Just continue on this thread, or Wait/WaitAll with try-catch:
        Try
            t2.Wait()

        Catch e As AggregateException

            For Each item In e.InnerExceptions
                Console.WriteLine(e.Message & " " & item.Message)
            Next
        Finally
            tokenSource2.Dispose()
        End Try

        Console.ReadKey()
    End Sub
End Module

Tam bir örnek için bkz . Nasıl yapılır: Görevi ve Alt Öğelerini İptal Etme.

Bir görev örneği kullanıcı kodu tarafından oluşturulan bir OperationCanceledException durumu gözlemlediğinde, özel durumun belirtecini ilişkili belirteciyle (Görevi oluşturan API'ye geçirilen belirteç) karşılaştırır. Belirteçler aynıysa ve belirtecin IsCancellationRequested özelliği döndürüyorsa true, görev bunu iptali onaylayıp İptal Edildi durumuna geçiş olarak yorumlar. Görevi beklemek için bir Wait veya WaitAll yöntemi kullanmıyorsanız, görev yalnızca durumunu olarak Canceledayarlar.

İptal Edildi durumuna geçirilen bir Görevi bekliyorsanız, bir System.Threading.Tasks.TaskCanceledException özel durum (bir AggregateException özel duruma sarmalanmış) oluşturulur. Bu özel durum, hatalı bir durum yerine başarılı iptali gösterir. Bu nedenle, görevin Exception özelliği döndürür null.

Belirtecin IsCancellationRequested özelliği döndürülüyorsa false veya özel durumun belirteci Görevin belirteciyle eşleşmiyorsa, OperationCanceledException normal bir özel durum olarak kabul edilir ve Bu da Görevin Hatalı duruma geçmesine neden olur. Diğer özel durumların varlığı da Görevin Hatalı duruma geçmesine neden olur. Tamamlanan görevin durumunu özelliğinde Status alabilirsiniz.

İptal istendikten sonra bir görev bazı öğeleri işlemeye devam edebilir.

Ayrıca bkz.