Derleyici Uyarısı (düzey 1) CS4014

Bu çağrı beklenmediği için, çağrı tamamlanmadan önce geçerli yöntemin yürütülmesi devam eder. çağrının await sonucuna işlecini uygulamayı göz önünde bulundurun.

Geçerli yöntem, bir veya döndüren Task ve await işlecini sonucta uygulamayan zaman uyumsuz bir Task<TResult> yöntemi çağırır. Zaman uyumsuz yöntem çağrısı zaman uyumsuz bir görev başlatır. Ancak hiçbir await işleç uygulanmadığından, program görevin tamamlanmasını beklemeden devam eder. Çoğu durumda, bu davranış beklediğiniz gibi değildir. Genellikle çağırma yönteminin diğer yönleri çağrının sonuçlarına bağlıdır veya çağrıyı içeren yöntemden dönmeden önce çağrılan yöntemin en az düzeyde tamamlanması beklenir.

Eşit derecede önemli bir sorun, çağrılan zaman uyumsuz yöntemde ortaya çıkan özel durumlara ne olduğudur. veya Task<TResult> döndüren Task bir yöntemde tetiklenen ve döndürülen görevde depolanan bir özel durum. Görevi beklemezseniz veya özel durumları açıkça denetlemezseniz, özel durum kaybolur. Görevi beklerseniz, özel durumu yeniden oluşturulur.

En iyi uygulama olarak, aramayı her zaman beklemelisiniz.

Yalnızca zaman uyumsuz çağrının tamamlanmasını beklemek istemediğinizden ve çağrılan yöntemin özel durum oluşturmayacağından eminseniz uyarıyı gizlemeyi düşünmelisiniz. Bu durumda, çağrının görev sonucunu bir değişkene atayarak uyarıyı gizleyebilirsiniz.

Aşağıdaki örnekte uyarıya nasıl neden olunacak, nasıl gizlenecek ve çağrı nasıl beklenir gösterilmektedir.

static async Task CallingMethodAsync(int millisecondsDelay)
{
    Console.WriteLine("  Entering calling method.");

    // Call #1.
    // Call an async method. Because you don't await it, its completion
    // isn't coordinated with the current method, CallingMethodAsync.
    // The following line causes warning CS4014.
    CalledMethodAsync(millisecondsDelay);

    // Call #2.
    // To suppress the warning without awaiting, you can assign the
    // returned task to a variable. The assignment doesn't change how
    // the program runs. However, recommended practice is always to
    // await a call to an async method.

    // Replace Call #1 with the following line.
    // Task delayTask = CalledMethodAsync(millisecondsDelay);

    // Call #3
    // To contrast with an awaited call, replace the unawaited call
    // (Call #1 or Call #2) with the following awaited call. Best
    // practice is to await the call.

    // await CalledMethodAsync(millisecondsDelay);

    Console.WriteLine("  Returning from calling method.");
}

static async Task CalledMethodAsync(int millisecondsDelay)
{
    Console.WriteLine("    Entering called method, starting and awaiting Task.Delay.");

    await Task.Delay(millisecondsDelay);

    Console.WriteLine("    Task.Delay is finished--returning from called method.");
}

Örnekte, Çağrı #1 veya Çağrı #2'yi seçerseniz, hem çağıranın hem de çağıranın CallingMethodAsync çağıranı tamamlandıktan sonra, kaydedilmemiş zaman uyumsuz yöntem CalledMethodAsync tamamlanır. Aşağıdaki çıktıdaki son satırda, çağrılan yöntem tamamlandığında gösterilir. Tam örnekte çağıran CallingMethodAsync olay işleyicisine giriş ve çıkış çıkışında işaretlenir.

Entering the Click event handler.
  Entering calling method.
    Entering called method, starting and awaiting Task.Delay.
  Returning from calling method.
Exiting the Click event handler.
    Task.Delay is finished--returning from called method.

Ayrıca, #pragma uyarı yönergelerini kullanarak derleyici uyarılarını gizleyebilirsiniz.

Örnek

Aşağıdaki konsol uygulaması, önceki örnekteki yöntemleri içerir. Aşağıdaki adımlar uygulamayı ayarlar.

  1. Bir konsol uygulaması oluşturun ve adını verin AsyncWarning.

  2. Visual Studio Code Düzenleyicisi'nde Program.cs dosyasını seçin.

  3. Program.cs dosyasında kodu aşağıdaki kodla değiştirin.

    using System;
    using System.Threading.Tasks;
    
    namespace AsyncWarning
    {
        class Program
        {
            static async Task Main()
            {
                Console.WriteLine("Entering Main() application entry point.");
    
                int millisecondsDelay = 2000;
                await CallingMethodAsync(millisecondsDelay);
    
                Console.WriteLine("Exiting Main() application entry point.");
    
                await Task.Delay(millisecondsDelay + 500);
            }
    
            static async Task CallingMethodAsync(int millisecondsDelay)
            {
                Console.WriteLine("  Entering calling method.");
    
                // Call #1.
                // Call an async method. Because you don't await it, its completion
                // isn't coordinated with the current method, CallingMethodAsync.
                // The following line causes warning CS4014.
                // CalledMethodAsync(millisecondsDelay);
    
                // Call #2.
                // To suppress the warning without awaiting, you can assign the
                // returned task to a variable. The assignment doesn't change how
                // the program runs. However, recommended practice is always to
                // await a call to an async method.
    
                // Replace Call #1 with the following line.
                //Task delayTask = CalledMethodAsync(millisecondsDelay);
    
                // Call #3
                // To contrast with an awaited call, replace the unawaited call
                // (Call #1 or Call #2) with the following awaited call. Best
                // practice is to await the call.
    
                // await CalledMethodAsync(millisecondsDelay);
    
                Console.WriteLine("  Returning from calling method.");
            }
    
            static async Task CalledMethodAsync(int millisecondsDelay)
            {
                Console.WriteLine("    Entering called method, starting and awaiting Task.Delay.");
    
                await Task.Delay(millisecondsDelay);
    
                Console.WriteLine("    Task.Delay is finished--returning from called method.");
            }
        }
    
        // Output with Call #1 or Call #2. (Wait for the last line to appear.)
    
        // Entering Main() application entry point.
        //   Entering calling method.
        //     Entering called method, starting and awaiting Task.Delay.
        //   Returning from calling method.
        // Exiting Main() application entry point.
        //     Task.Delay is finished--returning from called method.
    
        // Output with Call #3, which awaits the call to CalledMethodAsync.
    
        // Entering Main() application entry point.
        //   Entering calling method.
        //     Entering called method, starting and awaiting Task.Delay.
        //     Task.Delay is finished--returning from called method.
        //   Returning from calling method.
        // Exiting Main() application entry point.
    }
    
  4. Programı çalıştırmak için F5 anahtarını seçin.

Beklenen çıkış kodun sonunda görünür.

Ayrıca bkz.