рдЕрдкрдиреЗ рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рдореЗрдВ рдореИрдВрдиреЗ рдмрддрд╛рдпрд╛ рдХрд┐ рдХреИрд╕реЗ async / рдкреНрд░рддреАрдХреНрд╖рд┐рдд рдСрдкрд░реЗрдЯрд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ "рд╣реЛ рд╕рдХрддрд╛ рд╣реИ" рдореЛрдирдб рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рдПред рдЗрд╕ рдмрд╛рд░ рдореИрдВ рдЙрд╕реА рддрдХрдиреАрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдФрд░ рд▓реЛрдХрдкреНрд░рд┐рдп рдбрд┐рдЬрд╛рдЗрди рдкреИрдЯрд░реНрди "рд░реАрдбрд░ рдореЛрдирд╛рдб" рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рддрд░реАрдХрд╛ рдмрддрд╛рдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реВрдВред
рдпрд╣ рдкреИрдЯрд░реНрди рдлрд╝рдВрдХреНрд╢рди рдорд╛рдкрджрдВрдбреЛрдВ рдпрд╛ рд╕рд╛рдЭрд╛ рд╡реИрд╢реНрд╡рд┐рдХ рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдмрд┐рдирд╛ рдХреБрдЫ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдХреБрдЫ рд╕рдВрджрд░реНрдн рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдЖрд╢реНрд░рд┐рдд рдЗрдВрдЬреЗрдХреНрд╢рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдФрд░ рддрд░реАрдХрд╛ рдорд╛рдирд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:
class Config { public string Template; } public static async Task Main() { Console.WriteLine(await GreetGuys().Apply(new Config {Template = "Hi, {0}!"}));
рдХреНрд▓рд╛рд╕рд┐рдХ "рд░реАрдбрд░"
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЖрдЗрдП рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓рддреЗ рд╣реИрдВ рдХрд┐ async / рдкреНрд░рддреАрдХреНрд╖рд┐рдд рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреЗ рдмрд┐рдирд╛ рдореЛрдирд╛рдб рдХреЛ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
public class Config { public string Template; } public static class ClassicReader { public static void Main() { var greeter = GreetGuys(); Console.WriteLine(greeter.Apply(new Config{Template = "Hello, {0}"}));
(рд░реАрдбрд░)
public class Reader<T, TCtx> { private readonly Func<TCtx, T> _exec; public Reader(Func<TCtx, T> exec) => this._exec = exec; public T Apply(TCtx ctx) => this._exec(ctx); } public static class Reader { public static Reader<TJoin, TCtx> SelectMany<TIn, TOut, TCtx, TJoin>( this Reader<TIn, TCtx> source, Func<TIn, Reader<TOut, TCtx>> bind, Func<TIn, TOut, TJoin> join) => new Reader<TJoin, TCtx>(ctx => { var inValue = source.Apply(ctx); var outValue = bind(inValue).Apply(ctx); return join(inValue, outValue); }); }
рдХреЛрдб рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдпрд╣ C # рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рдирд╣реАрдВ рд▓рдЧрддрд╛ рд╣реИред рдХреЛрдИ рдЖрд╢реНрдЪрд░реНрдп рдирд╣реАрдВ, рдХреНрдпреЛрдВрдХрд┐ рдорда рдХрд╛рд░реНрдпрд╛рддреНрдордХ рднрд╛рд╖рд╛рдУрдВ рд╕реЗ рдЖрдП рд╣реИрдВ рдЬрд╣рд╛рдВ рд╕рдорд╛рди рдХреЛрдб рдХреЛ рдЕрдзрд┐рдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рддрд░реАрдХреЗ рд╕реЗ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдХреНрд▓рд╛рд╕рд┐рдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкреИрдЯрд░реНрди рдХреЗ рд╕рд╛рд░ рдХреЛ рд╕рдордЭрдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИ - рдХреБрдЫ рдХреЛрдб рдХреЗ рддрддреНрдХрд╛рд▓ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рдмрдЬрд╛рдп рдЗрд╕реЗ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдбрд╛рд▓ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдЗрд╕рдХреЗ рд╕рдВрджрд░реНрдн рддреИрдпрд╛рд░ рд╣реЛрдиреЗ рдкрд░ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
public static Reader<string, Config> Greet(string name) => new Reader<string, Config>(cfg => string.Format(cfg.Template, name));
SelectMany рдХрдИ рдРрд╕реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдПрдХ рд╣реА рдореЗрдВ рдЬреЛрдбрд╝ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдк рдПрдХ рдЙрдк-рджрд┐рдирдЪрд░реНрдпрд╛ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдХрд╛ рдирд┐рд╖реНрдкрд╛рджрди рддрдм рддрдХ рд╕реНрдердЧрд┐рдд рд░рд╣реЗрдЧрд╛ рдЬрдм рддрдХ рдХрд┐ рдЙрд╕рдХрд╛ рд╕рдВрджрд░реНрдн рд▓рд╛рдЧреВ рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддрд╛ред рджреВрд╕рд░реА рдУрд░, рд╡рд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдХреЛрдб рд▓рд┐рдЦрдиреЗ рд╕реЗ рдорд┐рд▓рддрд╛ рдЬреБрд▓рддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд╛ рдирд┐рд╖реНрдкрд╛рджрди рд░реЛрдХ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЕрдЧрд░ рдХреБрдЫ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдСрдкрд░реЗрд╢рди рдЪрд▓ рд░рд╣рд╛ рд╣реЛред рдЬрдм рдСрдкрд░реЗрд╢рди рдХрд╛ рдкрд░рд┐рдгрд╛рдо рддреИрдпрд╛рд░ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдирд┐рд╖реНрдкрд╛рджрди рдЬрд╛рд░реА рд░рд╣реЗрдЧрд╛ред рдПрдХ рдзрд╛рд░рдгрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╕рдВрдЪрд╛рд▓рди ( async / рдкреНрд░рддреАрдХреНрд╖рд╛ ) рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ C # рдмреБрдирд┐рдпрд╛рджреА рдврд╛рдВрдЪрд╛ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ "рд░реАрдбрд░" рдореЛрдирдб рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ ... рдпрд╣ рдзрд╛рд░рдгрд╛ рд╕рд╣реА рд╣реИ!
Async "рд░реАрдбрд░"
рдЕрдкрдиреЗ рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рдореЗрдВ рдореИрдВрдиреЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдерд╛ рдХрд┐ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рд╡рд╛рдкрд╕ рдЖрдпреЗ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдПрд╕реНрдХрд┐рдВрдЯ рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ async / рдкреНрд░рддреАрдХреНрд╖рд╛ рдСрдкрд░реЗрдЯрд░реЛрдВ рдкрд░ рдирд┐рдпрдВрддреНрд░рдг рдХреИрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВред рдЗрд╕ рдмрд╛рд░ рдЙрд╕реА рддрдХрдиреАрдХ рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЖрдЗрдП "рдкрд╛рдардХ" рд╡рд░реНрдЧ рд╕реЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛:
[AsyncMethodBuilder(typeof(ReaderTaskMethodBuilder<>))] public class Reader<T> : INotifyCompletion, IReader { ...
рдХрдХреНрд╖рд╛ рдореЗрдВ рджреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЬрд┐рдореНрдореЗрджрд╛рд░рд┐рдпрд╛рдВ рд╣реИрдВ (рд╕реИрджреНрдзрд╛рдВрддрд┐рдХ рд░реВрдк рд╕реЗ рд╣рдо 2 рдХрдХреНрд╖рд╛рдПрдВ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ):
- рдЬрдм рд╕рдВрджрд░реНрдн рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рдХреБрдЫ рдорд╛рди рдирд┐рдХрд╛рд▓рдирд╛ рдПрдХ рд╕рдВрджрд░реНрдн рдмрдирддрд╛ рд╣реИ
- рд░реАрдбрд░ рдЗрдВрд╕реНрдЯреЗрдВрд╕ рдХреА рдПрдХ рд▓рд┐рдВрдХ рдХреА рдЧрдИ рд╕реВрдЪреА рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдЬреЛ рдПрдХ рдХреЙрд▓ рдкрджрд╛рдиреБрдХреНрд░рдо рдкрд░ рдПрдХ рд╕рдВрджрд░реНрдн рд╡рд┐рддрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рдкреНрд░рддреНрдпреЗрдХ рдЬрд┐рдореНрдореЗрджрд╛рд░реА рдХреЗ рд▓рд┐рдП рд╣рдо рдПрдХ рдЕрд▓рдЧ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ:
private readonly Func<object, T> _extractor;
рдЬрдм рд░реАрдбрд░ рдХреНрд▓рд╛рд╕ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдкреНрд░рддреАрдХреНрд╖рд╛ рдСрдкрд░реЗрдЯрд░ рдХреЗ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЙрджрд╛рд╣рд░рдг рдПрдХ рдирд┐рд░рдВрддрд░рддрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдХреЛ рдПрдХ рд▓рд┐рдВрдХ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдЧрд╛, рдЬрд┐рд╕реЗ рдХреЗрд╡рд▓ рддрдм рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдЬрдм рдХреЛрдИ рдирд┐рд╖реНрдкрд╛рджрди рд╕рдВрджрд░реНрдн рд╣рд▓ рд╣реЛ рдЬрд╛рдП рдФрд░ рд╣рдо (рд╕рдВрджрд░реНрдн рд╕реЗ) рдХреБрдЫ рдбреЗрдЯрд╛ рдирд┐рдХрд╛рд▓ рд╕рдХреЗрдВ, рдЬреЛ рдХрд┐ рд╣реЛрдЧрд╛ рдирд┐рд░рдВрддрд░рддрд╛ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдорд╛рддрд╛-рдкрд┐рддрд╛ рдФрд░ рдмрдЪреНрдЪреЗ "рдкрд╛рдардХреЛрдВ" рдХреЗ рдмреАрдЪ рд╕рдВрдмрдВрдз рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдЗрдП рд╡рд┐рдзрд┐ рдмрдирд╛рдПрдБ:
private IReader _child; internal void SetChild(IReader reader) { this._child = reader; if (this._ctx != null) { this._child.SetCtx(this._ctx); } }
рдЬрд┐рд╕реЗ ReaderTaskMethodBuilder рдХреЗ рдЕрдВрджрд░ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛:
public class ReaderTaskMethodBuilder<T> { ... public void GenericAwaitOnCompleted<TAwaiter, TStateMachine>( ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine { if (awaiter is IReader reader) { this.Task.SetChild(reader); } awaiter.OnCompleted(stateMachine.MoveNext); } public Reader<T> Task { get; } }
SetChild рд╡рд┐рдзрд┐ рдХреЗ рдЕрдВрджрд░ рд╣рдо SetCtx рдХрд╣рддреЗ рд╣реИрдВ рдЬреЛ рдПрдХ рд╕рдВрджрд░реНрдн рдХреЛ рдкрджрд╛рдиреБрдХреНрд░рдо рддрдХ рдкреНрд░рдЪрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдпрджрд┐ рдЗрд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рдПрдХ рдПрдХреНрд╕рдЯреНрд░реИрдХреНрдЯрд░ рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ:
public void SetCtx(object ctx) { this._ctx = ctx; if (this._ctx != null) { this._child?.SetCtx(this._ctx); if (this._extractor != null) { this.SetResult(this._extractor(this._ctx)); } } }
SetResult рдПрдХ рд╕рдВрджрд░реНрдн рд╕реЗ рдирд┐рдХрд╛рд▓реЗ рдЧрдП рдорд╛рди рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдПрдХ рдирд┐рд░рдВрддрд░рддрд╛ рдХрд╣рддрд╛ рд╣реИ:
internal void SetResult(T result) { this._result = result; this.IsCompleted = true; this._continuation?.Invoke(); }
рдЙрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдЬрдм рдПрдХ рд░реАрдбрд░ рдЗрдВрд╕реНрдЯреЗрдВрд╕ рдореЗрдВ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝реНрдб "рдПрдХреНрд╕рдЯреНрд░реИрдХреНрдЯрд░" рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рддрдм SetResult рдХреЛ ReaderTaskMethodBuilder рджреНрд╡рд╛рд░рд╛ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬрдм рдПрдХ рдЬреЗрдирд░реЗрдЯ рдХреА рдЧрдИ рд╕реНрдЯреЗрдЯ рдорд╢реАрди рдЕрдкрдиреА рдЕрдВрддрд┐рдо рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдЬрд╛рддреА рд╣реИред
рд╡рд┐рдзрд┐ рд▓рд╛рдЧреВ рдХрд░реЗрдВ рдмрд╕ SetCtx рдХрд╣рддреЗ рд╣реИрдВ
public Reader<T> Apply(object ctx) { this.SetCtx(ctx); return this; }
рдЖрдк рдЬреАрдердм рдкрд░ рд╕рднреА рдХреЛрдб рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ ( рдпрджрд┐ рдпрд╣ рдЕрднреА рднреА рдЕрд╡рд░реБрджреНрдз рдирд╣реАрдВ рд╣реИ )
рдЕрдм, рдореИрдВ рдПрдХ рдФрд░ рдЕрдзрд┐рдХ рдпрдерд╛рд░реНрдерд╡рд╛рджреА рдЙрджрд╛рд╣рд░рдг рджрд┐рдЦрд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдХреИрд╕реЗ рдПрд╕рд┐рдВрдХреНрд╕ рд░реАрдбрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
рдЙрджрд╛рд╣рд░рдг рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрд▓рд┐рдХ рдХрд░реЗрдВ public static class ReaderTest { public class Configuration { public readonly int DataBaseId; public readonly string GreetingTemplate; public readonly string NameFormat; public Configuration(int dataBaseId, string greetingTemplate, string nameFormat) { this.DataBaseId = dataBaseId; this.GreetingTemplate = greetingTemplate; this.NameFormat = nameFormat; } } public static async Task Main() { int[] ids = { 1, 2, 3 }; Configuration[] configurations = { new Configuration(100, "Congratulations, {0}! You won {1}$!", "{0} {1}"), new Configuration(100, "┬бFelicidades, {0}! Ganaste {1} $", "{0}"), }; foreach (var configuration in configurations) { foreach (var userId in ids) {
рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреБрдЫ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЕрднрд┐рд╡рд╛рджрди рджрд┐рдЦрд╛рддрд╛ рд╣реИ рд▓реЗрдХрд┐рди рд╣рдо рдЙрдирдХреЗ рдирд╛рдореЛрдВ рдХреЛ рдкрд╣рд▓реЗ рд╕реЗ рдирд╣реАрдВ рдЬрд╛рдирддреЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕рд┐рд░реНрдл рдЙрдирдХрд╛ рдЖрдИрдбреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ "рдбреЗрдЯрд╛рдмреЗрд╕" рд╕реЗ рдЙрд╕ рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рдкрдврд╝рдирд╛ рд╣реЛрдЧрд╛ред рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рдХреБрдЫ рдХрдиреЗрдХреНрд╢рди рдЖрдЗрдбреЗрдВрдЯрд┐рдлрд╝рд╛рдпрд░ рдХреЛ рдЬрд╛рдирдирд╛ рд╣реЛрдЧрд╛ рдФрд░ рдЧреНрд░реАрдЯрд┐рдВрдЧ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рдЙрд╕рдХреЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА ... рдФрд░ рд╕рднреА рдЬрд╛рдирдХрд╛рд░реА рдкрд╛рд╕ рдХреА рдЧрдИ рд╣реИ рдЬреЛ рдХрд┐ async Reader рдХреЛ рдЧрд░реНрдд рдореЗрдВ рдбрд╛рд▓ рджреЗрдЧрд╛ред
Async "рд░реАрдбрд░" рдХреЗ рд╕рд╛рде рдирд┐рд░реНрднрд░рддрд╛ рдЗрдВрдЬреЗрдХреНрд╢рди
рдХреНрд▓рд╛рд╕рд┐рдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╕рд╛рде рддреБрд▓рдирд╛ рдореЗрдВ рдПрд╕рд┐рдВрдХреНрд╕ рд░реАрдбрд░ рдореЗрдВ рдПрдХ рджреЛрд╖ рд╣реИ - рд╣рдо рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкрд╛рд░рд┐рдд рд╕рдВрджрд░реНрдн рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред рдпрд╣ рд╕реАрдорд╛ рдЗрд╕ рддрдереНрдп рд╕реЗ рдЖрддреА рд╣реИ рдХрд┐ C # рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ Async рд╡рд┐рдзрд┐ рдмрд┐рд▓реНрдбрд░ рдХреНрд▓рд╛рд╕ рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреА рдЙрдореНрдореАрдж рд╣реИ (рд╢рд╛рдпрдж рдпрд╣ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рддрдп рд╣реЛ рдЬрд╛рдПрдЧрд╛)ред
рджреВрд╕рд░реА рдУрд░, рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдпрд╣ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЬреАрд╡рди рдореЗрдВ рд╢рд╛рдпрдж рдХреБрдЫ рдирд┐рд░реНрднрд░рддрд╛ рдЗрдВрдЬреЗрдХреНрд╢рди рдХрдВрдЯреЗрдирд░ рдХреЛ рдПрдХ рд╕рдВрджрд░реНрдн рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛:
public static class Reader { public static Reader<TService> GetService<TService>() => Reader<TService>.Read<IServiceProvider>(serviceProvider => (TService)serviceProvider .GetService(typeof(TService))); }
... private static async Reader<string> Greet(string userName) { var service = await Reader.GetService<IGreater>(); return service.GreetUser(userName); } ...
( рдпрд╣рд╛рдВ рдЖрдк рдПрдХ рдкреВрд░реНрдг рдЙрджрд╛рд╣рд░рдг рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ ... )
Async "рд╣реЛ рд╕рдХрддрд╛ рд╣реИ" рдХреЗ рд╡рд┐рдкрд░реАрдд, рдЬрд┐рд╕реЗ рдореИрдВрдиреЗ рдХрд┐рд╕реА рднреА рдЙрддреНрдкрд╛рджрди рдХреЛрдб рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрд╢рдВрд╕рд╛ рдирд╣реАрдВ рдХреА рдереА ( рдЕрдВрдд рдореЗрдВ рдмреНрд▓реЙрдХреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛ рдХреЗ рдХрд╛рд░рдг), рдореИрдВ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ async рд░реАрдбрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ "(" рдХреЗ рдЕрд▓рд╛рд╡рд╛ ") рдХреЗ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рдХреЗ рд░реВрдк рдореЗрдВ рдХрд░рдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реВрдВрдЧрд╛ред рдкрд╛рд░рдВрдкрд░рд┐рдХ рдирд┐рд░реНрднрд░рддрд╛ рдЗрдВрдЬреЗрдХреНрд╢рди рджреГрд╖реНрдЯрд┐рдХреЛрдг (рдЬрдм рд╕рднреА рдирд┐рд░реНрднрд░рддрд╛рдПрдВ рдПрдХ рдХреНрд▓рд╛рд╕ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдореЗрдВ рдкрд╛рд░рд┐рдд рд╣реЛ рдЬрд╛рддреА рд╣реИрдВ) рдХреНрдпреЛрдВрдХрд┐ рдкрд╛рдардХ рдХреЛ рдХреБрдЫ рдлрд╛рдпрджреЗ рд╣реИрдВ:
- рдЗрдВрдЬреЗрдХреНрд╢рди рдЧреБрдгреЛрдВ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╡рд░реНрдЧ рдЧреБрдгреЛрдВ рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрдХреНрд╖рд╛рдУрдВ рдореЗрдВ рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ - рд╕рднреА рддрд░реНрдХ рд╕реНрдерд┐рд░ рддрд░реАрдХреЛрдВ рд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред
- рд░реАрдбрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЧреИрд░ рдЕрд╡рд░реБрджреНрдз рдХреЛрдб рдмрдирд╛рдиреЗ рдХреЛ рдкреНрд░реЛрддреНрд╕рд╛рд╣рд┐рдд рдХрд░реЗрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рд╕рднреА рд╡рд┐рдзрд┐рдпрд╛рдБ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╣реЛрдВрдЧреА рдФрд░ рдХреБрдЫ рднреА рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛ рдЗрдирдкреБрдЯ / рдЖрдЙрдЯрдкреБрдЯ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рдЧреИрд░ рдЕрд╡рд░реБрджреНрдз рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдирд╣реАрдВ рд░реЛрдХреЗрдВрдЧреЗред
- рдХреЛрдб рдереЛрдбрд╝рд╛ рдФрд░ рдЕрдзрд┐рдХ "рдкрдардиреАрдп" рд╣реЛрдЧрд╛ - рд╣рд░ рдмрд╛рд░ рдЬрдм рд╣рдо рдкрд╛рдардХ рдХреЛ рдХреБрдЫ рд╡рд┐рдзрд┐ рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рджреЗрдЦрддреЗ рд╣реИрдВ рддреЛ рд╣рдореЗрдВ рдкрддрд╛ рдЪрд▓реЗрдЧрд╛ рдХрд┐ рдЗрд╕рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдирд┐рд╣рд┐рдд рд╕рдВрджрд░реНрдн рддрдХ рдкрд╣реБрдВрдЪ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
- Async Reader рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред
рдмреЗрд╢рдХ рдкрд╛рдардХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдЦрд┐рд▓рд╛рдл рдХреБрдЫ рддрд░реНрдХ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА, рдЗрди рд▓реЗрдЦреЛрдВ рдХрд╛ рдореБрдЦреНрдп рдЙрджреНрджреЗрд╢реНрдп рдпрд╣ рджрд┐рдЦрд╛рдирд╛ рд╣реИ рдХрд┐ рдХреИрд╕реЗ рдкреИрдЯрд░реНрди, рдЬреЛ рд╢реБрд░реВ рдореЗрдВ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдП рдЧрдП рдереЗ, рдХреЛ рдХреЛрдбрд┐рдВрдЧ рдХреА рдЕрдирд┐рд╡рд╛рд░реНрдп рд╢реИрд▓реА рдХреЗ рд▓рд┐рдП рдЕрдкрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рд╕рд░рд▓ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ рдЕрдзрд┐рдХрд╛рдВрд╢ рд▓реЛрдЧреЛрдВ рджреНрд╡рд╛рд░рд╛ рд╕рдордЭреЗрдВред