Aracılığıyla paylaş


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 CancellationTokenSource.Cancel yöntemini çağırması ve kullanıcı temsilcisinin işlemi zamanında sonlandırmasını içerir. Şu 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, TaskStatus.RanToCompletion durumuna geçirilir, TaskStatus.Canceled durumuna değil.

  • bir OperationCanceledException oluşturup iptalin istendiği belirteci geçirerek. Gerçekleştirmenin tercih edilen yolu, ThrowIfCancellationRequested yöntemini kullanmaktır. Bu şekilde iptal edilen bir görev, iptal edildi durumuna geçer ve çağıran kod, görevin iptal talebine yanıt verip vermediğini doğrulamak için bu durumu kullanabilir.

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

Uyarı

Belirteç, kullanıcı temsilcisine ve görev örneğine aktarılır.

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 Nasıl Yapılır: Görev ve Alt Öğelerini İptal Etme bölümüne bakın.

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 durumunu Canceled olarak ayarlamış olur.

İ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 istisna, bir hata yerine iptalin başarılı olduğunu 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 bakınız