Что-то давно этюдов не было. Не знаю тянет ли это на этюд, но попробую.
Сразу код: синхронный вариант и асинхронный вариант метода (SyncMethod и AsyncMethod):
| Синхронный |
| using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp29
{
class Program
{
static void SyncMethod(int i)
{
Task.Delay(1).Wait(); // Много разных асинхронных вызовов обессинхрониваем - не комильфо...
Task.Delay(1).Wait();
// Это убрать нельзя - эмуляция вызова асинхронного метода, который мы изменить не можем.
Thread.Sleep(1000);
Console.WriteLine(i);
}
static async Task Main(string[] args)
{
var sw = new Stopwatch();
Console.WriteLine("Start");
sw.Start();
var tasks = Enumerable
.Range(0, 1000)
.Select(i => Task.Factory.StartNew(() => { SyncMethod(i); }, TaskCreationOptions.LongRunning));
await Task.WhenAll(tasks);
sw.Stop();
Console.WriteLine("Done!");
Console.WriteLine($"ElapsedMilliseconds={sw.ElapsedMilliseconds}");
}
}
}
|
| |
и
| Асинхронный |
| using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp29
{
class Program
{
static async Task AsyncMethod(int i)
{
await Task.Delay(1); // Много разных асинхронных вызовов...
await Task.Delay(1);
// Это убрать нельзя - эмуляция вызова асинхронного метода, который мы изменить не можем.
Thread.Sleep(1000);
Console.WriteLine(i);
}
static async Task Main(string[] args)
{
var sw = new Stopwatch();
Console.WriteLine("Start");
sw.Start();
var tasks = Enumerable
.Range(0, 1000)
.Select(AsyncMethod);
await Task.WhenAll(tasks);
sw.Stop();
Console.WriteLine("Done!");
Console.WriteLine($"ElapsedMilliseconds={sw.ElapsedMilliseconds}");
}
}
}
|
| |
Метод внутри себя имеет синхронный длительный вызов (эмулируем с помощью Thread.Sleep), который во внешней библиотеке и переписать который в асинхронном варианте мы не можем.
Итак, если запустить код — то увидим, что синхронный вариант отработает за 1-2 секунды а асинхронный — около 1 минуты (примерно, не ждал до конца). Но есть минус — в синхронном варианте внутри мы вызываем внешние асинхронные методы и каждый раз вынуждены их обессинхронивать — что не гуд.
Вопрос: как сделать, чтобы асинхронный метод отрабатывал так же быстро?