Как мне преобразовать это в асинхронную задачу?

Учитывая следующий код ...

static void DoSomething(int id) {
    Thread.Sleep(50);
    Console.WriteLine(@"DidSomething({0})", id);
}

Я знаю, что могу преобразовать это в асинхронную задачу следующим образом ...

static async Task DoSomethingAsync(int id) {
    await Task.Delay(50);
    Console.WriteLine(@"DidSomethingAsync({0})", id);
}

И так, если я буду звонить несколько раз (Task.WhenAll), все будет быстрее и эффективнее, чем, возможно, использование Parallel.Foreach или даже вызов из цикла.

Но на минуту давайте представим, что Task.Delay () не существует, и мне действительно нужно использовать Thread.Sleep (); Я знаю, что на самом деле это не так, но это концептуальный код, и когда задержка / спящий режим обычно является операцией ввода-вывода, когда нет опции асинхронизации (такой как ранний EF).

Я попробовал следующее ...

static async Task DoSomethingAsync2(int id) {
    await Task.Run(() => {
        Thread.Sleep(50);
        Console.WriteLine(@"DidSomethingAsync({0})", id);
    });
}

Но, хотя он работает без ошибок, в соответствии сЛюсьен Висчик на самом деле это плохая практика, так как это просто раскручивание потоков из пула для выполнения каждой задачи (это также медленнее при использовании следующего консольного приложения - если вы переключаетесь между вызовами DoSomethingAsync и DoSomethingAsync2, вы можете увидеть значительную разницу во времени требуется, чтобы завершить) ...

static void Main(string[] args) {
    MainAsync(args).Wait();
}

static async Task MainAsync(String[] args) {

    List<Task> tasks = new List<Task>();
    for (int i = 1; i <= 1000; i++)
        tasks.Add(DoSomethingAsync2(i)); // Can replace with any version
    await Task.WhenAll(tasks);

}

Затем я попробовал следующее ...

static async Task DoSomethingAsync3(int id) {
    await new Task(() => {
        Thread.Sleep(50);
        Console.WriteLine(@"DidSomethingAsync({0})", id);
    });
}

Пересаживая это вместо оригинальной DoSomethingAsync, тест никогда не завершается, и на экране ничего не отображается!

Я также попробовал несколько других вариантов, которые либо не компилируются, либо не завершаются!

Итак, учитывая ограничение на то, что вы не можете вызывать какие-либо существующие асинхронные методы и должны выполнять как Thread.Sleep, так и Console.WriteLine в асинхронной задаче, как вы делаете это так же эффективно, как исходный код?

Цель для тех из вас, кто заинтересован, состоит в том, чтобы дать мне лучшее понимание того, как создавать мои собственные асинхронные методы, когда я не называю кого-либо еще. Несмотря на множество поисков, это, по-видимому, единственная область, где примеров действительно не хватает - хотя существует множество тысяч примеров вызова асинхронных методов, которые в свою очередь вызывают другие асинхронные методы, я не могу найти ни одного, который преобразует существующий метод void в асинхронную задачу, где нет вызова для другой асинхронной задачи, кроме тех, которые используют метод Task.Run (() => {}).

Ответы на вопрос(2)

Ваш ответ на вопрос