Zaman uyumsuz anaAsync Main

  • [x] önerilir[x] Proposed
  • [] Prototipi[ ] Prototype
  • [] Uygulama[ ] Implementation
  • [] Belirtimi[ ] Specification

ÖzetSummary

awaitGiriş noktasının döndürülmesini Task / Task<int> ve işaretlenmesini sağlayarak uygulamanın Main/EntryPoint yönteminde kullanılmasına izin verin async .Allow await to be used in an application's Main / entrypoint method by allowing the entrypoint to return Task / Task<int> and be marked async.

MotivasyonMotivation

C# öğrenirken, konsol tabanlı yardımcı programlar yazarken ve Main 'den çağrı yapmak için küçük test uygulamaları yazarken çok yaygın hale gelir await async .It is very common when learning C#, when writing console-based utilities, and when writing small test apps to want to call and await async methods from Main. Bugün, bu tür bir karmaşıklıktan await ayrı bir zaman uyumsuz yöntemde yapılacak şekilde zorlayarak, geliştiricilerin çalışmaya başlamak için aşağıdaki gibi bir demirbaş yazmasına neden olan ayrı bir zaman uyumsuz yöntemde yapılacak bir karmaşıklık düzeyi ekleyeceğiz:Today we add a level of complexity here by forcing such await'ing to be done in a separate async method, which causes developers to need to write boilerplate like the following just to get started:

public static void Main()
{
    MainAsync().GetAwaiter().GetResult();
}

private static async Task MainAsync()
{
    ... // Main body here
}

Bu demirbaş için gerekli olan gereksinimi kaldırabiliriz ve yalnızca ana kendisinin bu tür bir şekilde kullanılabilir hale geçmesine izin vererek başlamak daha kolay hale gelir async await .We can remove the need for this boilerplate and make it easier to get started simply by allowing Main itself to be async such that awaits can be used in it.

Ayrıntılı tasarımDetailed design

Şu anda Şu imzalara izin veriliyor entryPoints:The following signatures are currently allowed entrypoints:

static void Main()
static void Main(string[])
static int Main()
static int Main(string[])

İzin verilen entryPoints listesini şunları içerecek şekilde genişlettik:We extend the list of allowed entrypoints to include:

static Task Main()
static Task<int> Main()
static Task Main(string[])
static Task<int> Main(string[])

Uyumluluk risklerinden kaçınmak için, bu yeni imzalar yalnızca önceki küme için aşırı yükleme yoksa geçerli giriş noktaları olarak kabul edilir.To avoid compatibility risks, these new signatures will only be considered as valid entrypoints if no overloads of the previous set are present. Dil/derleyici, giriş noktasının olarak işaretlenmesini gerektirmez async , ancak kullanımları büyük çoğunluğunun bu şekilde işaretleneceğini bekleiyoruz.The language / compiler will not require that the entrypoint be marked as async, though we expect the vast majority of uses will be marked as such.

Bunlardan biri giriş noktası olarak tanımlandığında, derleyici bu kodlanmış yöntemlerden birini çağıran gerçek bir giriş noktası yöntemini sentezle birleştirmeyecektir:When one of these is identified as the entrypoint, the compiler will synthesize an actual entrypoint method that calls one of these coded methods:

  • static Task Main() , derleyicinin şu değerin eşdeğerini yayacaktır private static void $GeneratedMain() => Main().GetAwaiter().GetResult();static Task Main() will result in the compiler emitting the equivalent of private static void $GeneratedMain() => Main().GetAwaiter().GetResult();
  • static Task Main(string[]) , derleyicinin şu değerin eşdeğerini yayacaktır private static void $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();static Task Main(string[]) will result in the compiler emitting the equivalent of private static void $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();
  • static Task<int> Main() , derleyicinin şu değerin eşdeğerini yayacaktır private static int $GeneratedMain() => Main().GetAwaiter().GetResult();static Task<int> Main() will result in the compiler emitting the equivalent of private static int $GeneratedMain() => Main().GetAwaiter().GetResult();
  • static Task<int> Main(string[]) , derleyicinin şu değerin eşdeğerini yayacaktır private static int $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();static Task<int> Main(string[]) will result in the compiler emitting the equivalent of private static int $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();

Örnek kullanım: Example usage:

using System;
using System.Net.Http;

class Test
{
    static async Task Main(string[] args) =>
        Console.WriteLine(await new HttpClient().GetStringAsync(args[0]));
}

BulunmaktadırDrawbacks

Ana sakıncası, ek giriş noktası imzalarını desteklemeye yönelik ek karmaşıklıkdır.The main drawback is simply the additional complexity of supporting additional entrypoint signatures.

AlternatiflerAlternatives

Dikkate alınan diğer çeşitler:Other variants considered:

İzin veriliyor async void .Allowing async void. Kodun doğrudan çağrılması için semantiği aynı tutmanız gerekir, bu, oluşturulan bir giriş noktasının çağrı yapmasını zorlaştırır (görev döndürülmez).We need to keep the semantics the same for code calling it directly, which would then make it difficult for a generated entrypoint to call it (no Task returned). Bunun gibi iki farklı yöntem oluşturarak bunu çözebiliriz.We could solve this by generating two other methods, e.g.

public static async void Main()
{
   ... // await code
}

geldiğindebecomes

public static async void Main() => await $MainTask();

private static void $EntrypointMain() => Main().GetAwaiter().GetResult();

private static async Task $MainTask()
{
    ... // await code
}

Teşvik kullanımı konusunda da sorunlar vardır async void .There are also concerns around encouraging usage of async void.

Ad olarak "Main" yerine "MainAsync" kullanılıyor.Using "MainAsync" instead of "Main" as the name. Zaman uyumsuz sonek görev döndüren yöntemler için önerilse de öncelikle kitaplık işlevselliği hakkında, ana olmayan ve "Main" dışındaki ek giriş noktası adlarını destekleyen bu değer bu kadar önemli değildir.While the async suffix is recommended for Task-returning methods, that's primarily about library functionality, which Main is not, and supporting additional entrypoint names beyond "Main" is not worth it.

Çözümlenmemiş sorularUnresolved questions

yokn/a

Tasarım toplantılarıDesign meetings

yokn/a