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ısının await sonucuna işlecini uygulamayı göz önünde bulundurun.

Geçerli yöntem, a veya döndüren Task ve sonucta await işlecini 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 düşük düzeyde tamamlanması beklenir.

Eşit derecede önemli bir sorun, çağrılan zaman uyumsuz yöntemde ortaya çıkarılan özel durumlara ne olduğudur. veya döndüren TaskTask<TResult> bir yöntemde tetiklenen bir özel durum, döndürülen görevde depolanır. 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, her zaman çağrıyı beklemelisiniz.

Yalnızca zaman uyumsuz çağrının tamamlanmasını beklemek istemediğinizden ve çağrılan yöntemin özel durum oluşturmayeceğinden 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ının nasıl neden olduğu, nasıl gizlenecekleri ve çağrının 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, çağrılmayan zaman uyumsuz yöntem CalledMethodAsync hem çağıranın CallingMethodAsync hem de çağıranın çağıranı tamamlandıktan sonra tamamlanır. Aşağıdaki çıktıdaki son satır, çağrılan yöntem tamamlandığında size gösterilir. Tam örnekte çağıran CallingMethodAsync olay işleyicisine giriş ve çıkış çıkışta 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 tuşunu seçin.

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

Ayrıca bkz.