C # рдореЗрдВ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рд╕реБрдзрд╛рд░ рдХреЗ рд▓рд┐рдП рд╕рд░реНрд╡реЛрддреНрддрдо рдЕрднреНрдпрд╛рд╕

рд╕рднреА рдХреЛ рдирдорд╕реНрдХрд╛рд░ред рд╣рдордиреЗ рдкрд╛рдареНрдпрдХреНрд░рдо "рд╕реА # рдбреЗрд╡рд▓рдкрд░" рдХреА рд╢реБрд░реБрдЖрдд рдХреА рдкреВрд░реНрд╡ рд╕рдВрдзреНрдпрд╛ рдкрд░ рдПрдХ рдФрд░ рдЙрдкрдпреЛрдЧреА рд╕рд╛рдордЧреНрд░реА рдХрд╛ рдЕрдиреБрд╡рд╛рдж рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ рд╣реИ ред рдкрдврд╝рдиреЗ рдХрд╛ рдордЬрд╝рд╛ рд▓реЗрдВред




рдЪреВрдВрдХрд┐ рдореИрдВрдиреЗ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдХреНрд░рд┐рдЯреЛ рдХреЗ рд▓рд┐рдП C # рдореЗрдВ рд╕рд░реНрд╡реЛрддреНрддрдо рдкреНрд░рдерд╛рдУрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдмрдирд╛рдИ рд╣реИ, рдореИрдВрдиреЗ рд╕реЛрдЪрд╛ рдХрд┐ рдЗрд╕реЗ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд░реВрдк рд╕реЗ рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ред рдЗрд╕ рд▓реЗрдЦ рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рдХреЛрдб рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХреА рдПрдХ рдЕрдзреВрд░реА рд╕реВрдЪреА рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рд╣реИ рдЬрд┐рд╕реЗ рдпрд╛ рддреЛ рдЯрд╛рд▓рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рд╕рдВрджрд┐рдЧреНрдз рд╣реИрдВ, рдпрд╛ рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рд╕рд┐рд░реНрдл рдЦрд░рд╛рдм рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред рд╕реВрдЪреА рдереЛрдбрд╝реА рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд▓рдЧ рд╕рдХрддреА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╕рдВрджрд░реНрдн рд╕реЗ рдереЛрдбрд╝рд╛ рдмрд╛рд╣рд░ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рд╕рднреА рддрддреНрд╡ рд╣рдорд╛рд░реЗ рдХреЛрдб рдореЗрдВ рдХреБрдЫ рдмрд┐рдВрджреБ рдкрд░ рдкрд╛рдП рдЧрдП рдФрд░ рдЙрддреНрдкрд╛рджрди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рдХрд╛рд░рдг рдмрдиреЗред рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдЕрдЪреНрдЫреА рд░реЛрдХрдерд╛рдо рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рдо рдХрд░реЗрдЧрд╛ рдФрд░ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдЖрдкрдХреА рдЧрд▓рддрд┐рдпреЛрдВ рдХреЛ рд░реЛрдХреЗрдЧрд╛ред

рдпрд╣ рднреА рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдХреНрд░рд┐рдЯреЛ рд╡реЗрдм рд╕реЗрд╡рд╛рдПрдВ рдЙрдЪреНрдЪ-рдкреНрд░рджрд░реНрд╢рди рдХреЛрдб рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреА рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЕрдХреНрд╖рдо рдХреЛрдб рд╕реЗ рдмрдЪрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЕрдзрд┐рдХрд╛рдВрд╢ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ, рдЗрдирдореЗрдВ рд╕реЗ рдХреБрдЫ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХреЛ рдмрджрд▓рдиреЗ рд╕реЗ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рдареЛрд╕ рдЕрдВрддрд░ рдирд╣реАрдВ рд╣реЛрдЧрд╛ред

рдФрд░ рдЕрдВрддрд┐рдо, рд▓реЗрдХрд┐рди рдХрдо рд╕реЗ рдХрдо, рдХреБрдЫ рдмрд┐рдВрджреБрдУрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП ConfigureAwait) рдкрд░ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХрдИ рд▓реЗрдЦреЛрдВ рдореЗрдВ рдЪрд░реНрдЪрд╛ рдХреА рдЧрдИ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЙрди рдкрд░ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдирд╣реАрдВ рд▓рд┐рдЦреВрдВрдЧрд╛ред рд▓рдХреНрд╖реНрдп рдЙрди рдмрд┐рдВрджреБрдУрдВ рдХреА рдПрдХ рдХреЙрдореНрдкреИрдХреНрдЯ рд╕реВрдЪреА рдмрдирд╛рдирд╛ рд╣реИ, рдЬрд┐рди рдкрд░ рдЖрдкрдХреЛ рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдЙрдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╕реНрддреГрдд рддрдХрдиреАрдХреА рдЧрдгрдирд╛ рди рджреЗрдВред

рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХреЛрдб рдХреЗ рд▓рд┐рдП рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд░рд╣рд╛ рд╣реИ


рдХрднреА рднреА рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдЕрдзреВрд░реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рди рдХрд░реЗрдВред рдЗрд╕ рдкрд░ рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рддрдХ рд╕реАрдорд┐рдд рдирд╣реАрдВ рд╣реИ: Task.Wait, Task.Result, Task.GetAwaiter().GetResult(), Task.WaitAny, Task.WaitAllред

рд╕рд╛рдорд╛рдиреНрдпреАрдХрд░рдг рдХреЗ рд░реВрдк рдореЗрдВ: рджреЛ рдкреВрд▓ рдереНрд░реЗрдбреНрд╕ рдХреЗ рдмреАрдЪ рдХреЛрдИ рднреА рд╕рдордХрд╛рд▓рд┐рдХ рд╕рдВрдмрдВрдз рдкреВрд▓ рдореЗрдВ рдХрдореА рдХрд╛ рдХрд╛рд░рдг рдмрди рд╕рдХрддрд╛ рд╣реИред рдЗрд╕ рдШрдЯрдирд╛ рдХреЗ рдХрд╛рд░рдгреЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ ред

ConfigureAwait


рдпрджрд┐ рдЖрдкрдХрд╛ рдХреЛрдб рдПрдХ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рд╕рдВрджрд░реНрдн рд╕реЗ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рддреЛ ConfigureAwait(false)рдЕрдкрдиреА рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХреЙрд▓ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред

рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ ConfigureAwait рдХрд┐рд╕реА рдХреАрд╡рд░реНрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордпawait рдпрд╣ рдХреЗрд╡рд▓ рдЙрдкрдпреЛрдЧреА рд╣реИ ред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрди рдХреЛрдб рдЕрд░реНрдерд╣реАрди рд╣реИ:

//  ConfigureAwait        
var result = ProcessAsync().ConfigureAwait(false).GetAwaiter().GetResult();

async рд╢реВрдиреНрдп


рдХрднреА рдЙрдкрдпреЛрдЧ рди рдХрд░реЗрдВasync void ред async voidрд╡рд┐рдзрд┐ рдореЗрдВ рдлреЗрдВрдХрд╛ рдЧрдпрд╛ рдЕрдкрд╡рд╛рдж рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рд╕рдВрджрд░реНрдн рдХреЗ рд▓рд┐рдП рдкреНрд░рдЪрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЖрдорддреМрд░ рдкрд░ рдкреВрд░реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдХреНрд░реИрд╢ рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░рдг рдмрдирддрд╛ рд╣реИред

рдпрджрд┐ рдЖрдк рдЕрдкрдиреА рд╡рд┐рдзрд┐ рдореЗрдВ рдХрд╛рд░реНрдп рдХреЛ рд╡рд╛рдкрд╕ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдЖрдк рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд▓рд╛рдЧреВ рдХрд░ рд░рд╣реЗ рд╣реИрдВ), рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХреЛрдб рдХреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рд╡рд┐рдзрд┐ рдкрд░ рд▓реЗ рдЬрд╛рдПрдВ рдФрд░ рдЗрд╕реЗ рдХреЙрд▓ рдХрд░реЗрдВ:

interface IInterface
{
    void DoSomething();
}

class Implementation : IInterface
{
    public void DoSomething()
    {
        //      ,
        //      
        _ = DoSomethingAsync();
    }

    private async Task DoSomethingAsync()
    {
        await Task.Delay(100);
    }
}

рдЬрдм рднреА рд╕рдВрднрд╡ рд╣реЛ async рд╕реЗ рдмрдЪреЗрдВ


рдЖрджрдд рд╕реЗ рдмрд╛рд╣рд░ рдпрд╛ рдорд╛рдВрд╕рдкреЗрд╢рд┐рдпреЛрдВ рдХреА рд╕реНрдореГрддрд┐ рдХреЗ рдХрд╛рд░рдг, рдЖрдк рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ:

public async Task CallAsync()
{
    var client = new Client();
    return await client.GetAsync();
}

рд╣рд╛рд▓рд╛рдБрдХрд┐ рдпрд╣ рдХреЛрдб рд╢рдмреНрджрдмрджреНрдз рд░реВрдк рд╕реЗ рд╕рд╣реА рд╣реИ, asyncрдпрд╣рд╛рдВ рдХрд┐рд╕реА рдХреАрд╡рд░реНрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдЕрддреНрдпрдзрд┐рдХ рд▓реЛрдб рд╡рд╛рд▓реЗ рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдУрд╡рд░рд╣реЗрдб рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдЬрдм рднреА рд╕рдВрднрд╡ рд╣реЛ, рдЗрд╕рд╕реЗ рдмрдЪрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ:

public Task CallAsync()
{
    var client = new Client();
    return _client.GetAsync();
}

рд╣рд╛рд▓рд╛рдБрдХрд┐, рдзреНрдпрд╛рди рд░рдЦреЗрдВ рдХрд┐ рдЖрдк рдЗрд╕ рдЕрдиреБрдХреВрд▓рди рдХрд╛ рд╕рд╣рд╛рд░рд╛ рдирд╣реАрдВ рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВ рдЬрдм рдЖрдкрдХрд╛ рдХреЛрдб рдмреНрд▓реЙрдХреЛрдВ рдореЗрдВ рд▓рд┐рдкрдЯрд╛ рд╣реЛ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, try/catchрдпрд╛ using):

public async Task Correct()
{
    using (var client = new Client())
    {
        return await client.GetAsync();
    }
}

public Task Incorrect()
{
    using (var client = new Client())
    {
        return client.GetAsync();
    }
}

рдЧрд▓рдд рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ ( Incorrect()), GetAsyncрдХреЙрд▓ рдкреВрд░рд╛ рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдЧреНрд░рд╛рд╣рдХ рдХреЛ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ , рдХреНрдпреЛрдВрдХрд┐ рдЙрдкрдпреЛрдЧ рдмреНрд▓реЙрдХ рдХреЗ рдЕрдВрджрд░ рдХрд╛рд░реНрдп рдкреНрд░рддреАрдХреНрд╖рд╛ рд╕реЗ рдЕрдкреЗрдХреНрд╖рд┐рдд рдирд╣реАрдВ рд╣реИред

рдХреНрд╖реЗрддреНрд░реАрдп рддреБрд▓рдирд╛


рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХреНрд╖реЗрддреНрд░реАрдп рддреБрд▓рдирд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдХрд╛рд░рдг рдирд╣реАрдВ рд╣реИ, рддреЛ рд╣рдореЗрд╢рд╛ рдХреНрд░рдорд┐рдХ рддреБрд▓рдирд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ ред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЖрдВрддрд░рд┐рдХ рдЕрдиреБрдХреВрд▓рди рдХреЗ рдХрд╛рд░рдг, рдпрд╣ рдПрди-рдпреВрдПрд╕ рдбреЗрдЯрд╛ рдкреНрд░рд╕реНрддреБрддрд┐ рд░реВрдкреЛрдВ рдХреЗ рд▓рд┐рдП рдЬреНрдпрд╛рджрд╛ рдорд╛рдпрдиреЗ рдирд╣реАрдВ рд░рдЦрддрд╛ рд╣реИ, рддреБрд▓рдирд╛ рдЕрдиреНрдп рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рдкреНрд░рд╕реНрддреБрддрд┐ рд░реВрдкреЛрдВ (рдФрд░ рд▓рд┐рдирдХреНрд╕ рдкрд░ рдкрд░рд┐рдорд╛рдг рдХреЗ рджреЛ рдЖрджреЗрд╢реЛрдВ рдХреЗ рд▓рд┐рдП!) рдХреЗ рд▓рд┐рдП рдкрд░рд┐рдорд╛рдг рдзреАрдорд╛ рдХрд╛ рдПрдХ рдЖрджреЗрд╢ рд╣реИ!)ред рдЪреВрдВрдХрд┐ рдЕрдзрд┐рдХрд╛рдВрд╢ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ рд╕реНрдЯреНрд░рд┐рдВрдЧ рддреБрд▓рдирд╛ рдПрдХ рд▓рдЧрд╛рддрд╛рд░ рдСрдкрд░реЗрд╢рди рд╣реИ, рдЗрд╕рд▓рд┐рдП рдУрд╡рд░рд╣реЗрдб рдореЗрдВ рдХрд╛рдлреА рд╡реГрджреНрдзрд┐ рд╣реЛрддреА рд╣реИред

рд╕рдорд╡рд░реНрддреАрдмрд╛рдЧ <рдЯреА>


ConcurrentBag<T>рдмреЗрдВрдЪрдорд╛рд░реНрдХрд┐рдВрдЧ рдХреЗ рдмрд┐рдирд╛ рдХрднреА рднреА рдЙрдкрдпреЛрдЧ рди рдХрд░реЗрдВ ред рдпрд╣ рд╕рдВрдЧреНрд░рд╣ рдмрд╣реБрдд рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ (рдЬрдм рдЕрдзрд┐рдХрд╛рдВрд╢ рд╕рдордп рдЙрд╕ рдкрдВрдХреНрддрд┐ рджреНрд╡рд╛рд░рд╛ рдкрдВрдХреНрддрд┐ рд╕реЗ рдмрд╛рд╣рд░ рд░рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ рдЗрд╕реЗ рдкрдВрдХреНрддрд┐рдмрджреНрдз рдХрд░рддрд╛ рд╣реИ) рдФрд░ рдЕрдиреНрдп рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рдкрд░ рдЧрдВрднреАрд░ рдкреНрд░рджрд░реНрд╢рди рд╕рдорд╕реНрдпрд╛рдУрдВ рд╕реЗ рдЧреНрд░рд╕реНрдд рд╣реЛрддрд╛ рд╣реИред рдпрджрд┐ рдЖрдкрдХреЛ рдереНрд░реЗрдб-рд╕реБрд░рдХреНрд╖рд┐рдд рд╕рдВрдЧреНрд░рд╣ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ ConcurrentQueue <T рдкрд╕рдВрдж рдХрд░реЗрдВ> ред

ReaderWriterLock / ReaderWriterLockSlim <T рдмреЗрдВрдЪрдорд╛рд░реНрдХрд┐рдВрдЧ рдХреЗ рдмрд┐рдирд╛ >
рдХрднреА рдЙрдкрдпреЛрдЧ рди рдХрд░реЗрдВ ред ReaderWriterLock<T>/ReaderWriterLockSlim<T>рдпрджреНрдпрдкрд┐ рдкрд╛рдардХреЛрдВ рдФрд░ рд▓реЗрдЦрдХреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп рдЗрд╕ рддрд░рд╣ рдХреЗ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рдЖрджрд┐рдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЖрдХрд░реНрд╖рдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рдХреА рд▓рд╛рдЧрдд рд╕рд░рд▓ Monitor(рдХреАрд╡рд░реНрдб рдХреЗ рд╕рд╛рде рдЙрдкрдпреЛрдЧ lock) рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╣реИ ред рдпрджрд┐ рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЕрдиреБрднрд╛рдЧ рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдкрд╛рдардХреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдмрд╣реБрдд рдмрдбрд╝реА рдирд╣реАрдВ рд╣реИ, рддреЛ рдмрдврд╝реА рд╣реБрдИ рдУрд╡рд░рд╣реЗрдб рдХреЛ рдЕрд╡рд╢реЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрдЧрд╛рдорд┐рддрд┐ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реЛрдЧреА, рдФрд░ рдХреЛрдб рдмрджрддрд░ рдХрд╛рдо рдХрд░реЗрдЧрд╛ред

рд╡рд┐рдзрд┐ рд╕рдореВрд╣реЛрдВ рдХреЗ рдмрдЬрд╛рдп рд▓рдВрдмреЛ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рджреЗрдВ


рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:

public IEnumerable<int> GetItems()
{
    return _list.Where(i => Filter(i));
}
private static bool Filter(int element)
{
    return i % 2 == 0;
}

рд░реЗрд╕реНрдореНрдкрд░ рдПрдХ рд▓реИрдореНрдмрдбрд╛ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдмрд┐рдирд╛ рдкреБрдирд░реНрд▓реЗрдЦрди рдХреЛрдб рдХрд╛ рд╕реБрдЭрд╛рд╡ рджреЗрддрд╛ рд╣реИ, рдЬреЛ рдереЛрдбрд╝рд╛ рд╕рд╛рдл рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ:

public IEnumerable<int> GetItems()
{
    return _list.Where(Filter);
}
private static bool Filter(int element)
{
    return i % 2 == 0;
}

рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдпрд╣ рдкреНрд░рддреНрдпреЗрдХ рдХреЙрд▓ рдХреЗ рд▓рд┐рдП рдЧрддрд┐рд╢реАрд▓ рдореЗрдореЛрд░реА рдХреЗ рдЖрд╡рдВрдЯрди рдХреА рдУрд░ рдЬрд╛рддрд╛ рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдХреЙрд▓ рд╕рдВрдХрд▓рд┐рдд рдХрд░рддрд╛ рд╣реИ:

public IEnumerable<int> GetItems()
{
    return _list.Where(new Predicate<int>(Filter));
}
private static bool Filter(int element)
{
    return i % 2 == 0;
}

рдпрджрд┐ рдХреЛрдб рдХреЛ рднрд╛рд░реА рд▓реЛрдб рд╡рд╛рд▓реЗ рдЦрдВрдб рдореЗрдВ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЗрд╕рд╕реЗ рдкреНрд░рджрд░реНрд╢рди рдкрд░ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдкреНрд░рднрд╛рд╡ рдкрдбрд╝ рд╕рдХрддрд╛ рд╣реИред

рд▓реИрдореНрдмреНрдбрд╛ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдХрдВрдкрд╛рдЗрд▓рд░ рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝реЗрд╢рди рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рдЬреЛ рдПрдХ рд╕реНрдерд┐рд░ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдХреЛ рдХреИрд╢ рдХрд░рддрд╛ рд╣реИ, рдЖрд╡рдВрдЯрди рд╕реЗ рдмрдЪрддрд╛ рд╣реИред рдпрд╣ рдХреЗрд╡рд▓ рддрднреА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдЬрдм Filterрд╕реНрдереИрддрд┐рдХред рдпрджрд┐ рдирд╣реАрдВ, рддреЛ рдЖрдк рд╕реНрд╡рдпрдВ рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдХреЛ рдХреИрд╢ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

private Predicate<int> _filter;

public Constructor()
{
    _filter = new Predicate<int>(Filter);
}

public IEnumerable<int> GetItems()
{
    return _list.Where(_filter);
}

private bool Filter(int element)
{
    return i % 2 == 0;
}

рдПрдирд░рдЬреЗрд╢рдВрд╕ рдХреЛ рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдореЗрдВ рдмрджрд▓реЗрдВ


рдХреЙрд▓рд┐рдВрдЧ Enum.ToStringрдореЗрдВ .netрдХрд╛рдлреА рдорд╣рдВрдЧрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдЕрдВрджрд░ рдХрдиреНрд╡рд░реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдкреИрдХреЗрдЬрд┐рдВрдЧ рд╕рдВрд░рдЪрдирд╛ рднрдбрд╝рдХрд╛рддреА рдкрд░ рдЖрднрд╛рд╕реА рд╡рд┐рдзрд┐ рдмреБрд▓рд╛ рд╣реИред рдЗрд╕рд╕реЗ рдЬрд┐рддрдирд╛ рд╣реЛ рд╕рдХреЗ рдмрдЪрдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЧрдгрдирд╛рдУрдВ рдХреЛ рдЕрдХреНрд╕рд░ рдирд┐рд░рдВрддрд░ рддрд╛рд░реЛрдВ рд╕реЗ рдмрджрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

//       Numbers.One, Numbers.Two, ...
public enum Numbers
{
    One,
    Two,
    Three
}

public static class Numbers
{
    public const string One = "One";
    public const string Two = "Two";
    public const string Three = "Three";
}

рдпрджрд┐ рдЖрдкрдХреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдПрдиреНрдпреВрдорд░реЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдУрд╡рд░рд╣реЗрдб рдХреЛ рдкрд░рд┐рд╢реЛрдзрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╢рдмреНрджрдХреЛрд╢ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдореВрд▓реНрдп рдХреЛ рдХреИрд╢рд┐рдВрдЧ рдХрд░рдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред

рдЧрдгрдирд╛ рдХреА рддреБрд▓рдирд╛


рдиреЛрдЯ: рдпрд╣ .net рдХреЛрд░ рдореЗрдВ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдирд╣реАрдВ рд╣реИ, рд╕рдВрд╕реНрдХрд░рдг 2.1 рдХреЗ рдмрд╛рдж рд╕реЗ, рдЕрдиреБрдХреВрд▓рди JIT рджреНрд╡рд╛рд░рд╛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдЬрдм рдПрдиреНрдпреБрдорд░реЗрд╢рдиреНрд╕ рдХреЛ рдЭрдВрдбреЗ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдХрд░реНрд╖рдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ Enum.HasFlag:

[Flags]
public enum Options
{
    Option1 = 1,
    Option2 = 2,
    Option3 = 4
}

private Options _option;

public bool IsOption2Enabled()
{
    return _option.HasFlag(Options.Option2);
}

рдпрд╣ рдХреЛрдб рдЖрд╡рдВрдЯрди рдХреЗ рд╕рд╛рде рджреЛ рдкреИрдХреЗрдЬреЛрдВ рдХреЛ рдЙрдХрд╕рд╛рддрд╛ рд╣реИ: рдПрдХ рд░реВрдкрд╛рдВрддрд░рдг рдХреЗ Options.Option2рд▓рд┐рдП EnumрдФрд░ рджреВрд╕рд░рд╛ HasFlagрд╕рдВрд░рдЪрдирд╛ рдХреЗ рд▓рд┐рдП рд╡рд░реНрдЪреБрдЕрд▓ рдХреЙрд▓ рдХреЗ рд▓рд┐рдПред рдЗрд╕рд╕реЗ рдпрд╣ рдХреЛрдб рдмрд╣реБрдд рдорд╣рдВрдЧрд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рдЖрдкрдХреЛ рдкрдардиреАрдпрддрд╛ рдХрд╛ рддреНрдпрд╛рдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рдмрд╛рдЗрдирд░реА рдСрдкрд░реЗрдЯрд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП:

public bool IsOption2Enabled()
{
    return (_option & Options.Option2) == Options.Option2;
}

рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рддреБрд▓рдирд╛ рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди


рддреБрд▓рдирд╛рдУрдВ рдореЗрдВ рдПрдХ рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЬрдм рдПрдХ рд╢рдмреНрджрдХреЛрд╢ рдХреЗ рд▓рд┐рдП рдПрдХ рдХреБрдВрдЬреА рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ), рдЖрдкрдХреЛ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ Equals/GetHashCodeред рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдмрд╣реБрдд рдзреАрдорд╛ рд╣реИред Resharper рджреНрд╡рд╛рд░рд╛ рдЙрддреНрдкрдиреНрди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЖрдорддреМрд░ рдкрд░ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реИред

рдЖрдк рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдпрд╣рд╛рдБ рдФрд░ рдЬрд╛рди рд╕рдХрддреЗ рд╣реИрдВ: devblogs.microsoft.com/premier-developer/performance-implication-of-default-struct-equality-in-c

рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЗ рд╕рд╛рде рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рдЕрдиреБрдЪрд┐рдд рдкреИрдХреЗрдЬрд┐рдВрдЧ рд╕реЗ рдмрдЪреЗрдВ


рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:

public class IntValue : IValue
{
}

public void DoStuff()
{
    var value = new IntValue();

    LogValue(value);
    SendValue(value);
}

public void SendValue(IValue value)
{
    // ...
}

public void LogValue(IValue value)
{
    // ...
}

IntValueрдЧрддрд┐рд╢реАрд▓ рд╕реНрдореГрддрд┐ рдХреЛ рдЖрд╡рдВрдЯрд┐рдд рдХрд░рдиреЗ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрд░рдЪрд┐рдд рдХрд░реЗрдВ, рдЖрдХрд░реНрд╖рдХ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдЪреВрдВрдХрд┐ AddValueрдФрд░ SendValueрдЕрдкреЗрдХреНрд╖рд┐рдд рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реИрдВ, рдФрд░ рдЗрдВрдЯрд░рдлреЗрд╕ рдореЗрдВ рд╕рдВрджрд░реНрдн рд╢рдмреНрджрд╛рд░реНрде рд╣реИрдВ, рдЗрд╕ "рдЕрдиреБрдХреВрд▓рди" рдХреЗ рд▓рд╛рднреЛрдВ рдХреЛ рдирдХрд╛рд░рддреЗ рд╣реБрдП, рдореВрд▓реНрдп рдХреЛ рд╣рд░ рдХреЙрд▓ рдХреЗ рд╕рд╛рде рдкреИрдХ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЗрд╕рд╕реЗ рднреА рдЕрдзрд┐рдХ рд╕реНрдореГрддрд┐ рдЖрд╡рдВрдЯрди рд╣реЛрдВрдЧреЗ рдпрджрд┐ рдпрд╣ IntValueрдПрдХ рд╡рд░реНрдЧ рдерд╛, рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдХреЙрд▓ рдХреЗ рд▓рд┐рдП рдореВрд▓реНрдп рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рдкреИрдХ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рдпрджрд┐ рдЖрдк рдПрдХ рдПрдкреАрдЖрдИ рд▓рд┐рдЦ рд░рд╣реЗ рд╣реИрдВ рдФрд░ рдХреБрдЫ рдореВрд▓реНрдпреЛрдВ рдХреЛ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╕рд╛рдорд╛рдиреНрдп рддрд░реАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рджреЗрдЦреЗрдВ:

public struct IntValue : IValue
{
}

public void DoStuff()
{
    var value = new IntValue();

    LogValue(value);
    SendValue(value);
}

public void SendValue<T>(T value) where T : IValue
{
    // ...
}

public void LogValue<T>(T value) where T : IValue
{
    // ...
}

рдпрджреНрдпрдкрд┐ рдЗрди рддрд░реАрдХреЛрдВ рдХрд╛ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рд░реВрдк рд╕реЗ рд░реВрдкрд╛рдВрддрд░рдг рдкрд╣рд▓реА рдирдЬрд╝рд░ рдореЗрдВ рдмреЗрдХрд╛рд░ рд▓рдЧрддрд╛ рд╣реИ, рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЖрдкрдХреЛ IntValueрд╕рдВрд░рдЪрдирд╛ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдЖрд╡рдВрдЯрди рдХреЗ рд╕рд╛рде рдкреИрдХреЗрдЬрд┐рдВрдЧ рд╕реЗ рдмрдЪрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ ред

рд░рджреНрджрдХрд░рдгрдЯреЛрдХрди рд╕рджрд╕реНрдпрддрд╛рдПрдБ рд╣рдореЗрд╢рд╛ рдЗрдирд▓рд╛рдЗрди


рдЬрдм рдЖрдк рд░рджреНрдж рдХрд░рддреЗ рд╣реИрдВ CancellationTokenSource, рддреЛ рд╕рднреА рд╕рджрд╕реНрдпрддрд╛рдПрдВ рд╡рд░реНрддрдорд╛рди рдереНрд░реЗрдб рдХреЗ рдЕрдВрджрд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХреА рдЬрд╛рдПрдВрдЧреАред рдпрд╣ рдЕрдирд┐рдпреЛрдЬрд┐рдд рд╡рд┐рд░рд╛рдо рдпрд╛ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдЧрддрд┐рд░реЛрдз рдкреИрджрд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реИред

var cts = new CancellationTokenSource();
cts.Token.Register(() => Thread.Sleep(5000));
cts.Cancel(); //     5 

рдЖрдк рдЗрд╕ рд╡реНрдпрд╡рд╣рд╛рд░ рд╕реЗ рдмрдЪ рдирд╣реАрдВ рд╕рдХрддреЗред рдЗрд╕рд▓рд┐рдП, рд░рджреНрдж рдХрд░рддреЗ рд╕рдордп CancellationTokenSource, рдЕрдкрдиреЗ рдЖрдк рд╕реЗ рдкреВрдЫреЗрдВ рдХрд┐ рдХреНрдпрд╛ рдЖрдк рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рдЕрдкрдиреЗ рд╡рд░реНрддрдорд╛рди рдзрд╛рдЧреЗ рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗ рд╕рдХрддреЗ рд╣реИрдВред рдпрджрд┐ рдЙрддреНрддрд░ рдирд╣реАрдВ рд╣реИ, рддреЛ рдереНрд░реЗрдб рдкреВрд▓ рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЙрд▓ рдХреЛ CancelрдЕрдВрджрд░ рд▓рдкреЗрдЯреЗрдВ Task.Runред

TaskCompletionSource рдирд┐рд░рдВрддрд░рддрд╛ рдЕрдХреНрд╕рд░ рдЗрдирд▓рд╛рдЗрди рд╣реЛрддреА рд╣реИ


рд╕рджрд╕реНрдпрддрд╛ рдХреА рддрд░рд╣ CancellationToken, рдирд┐рд░рдВрддрд░рддрд╛ TaskCompletionSourceрдЕрдХреНрд╕рд░ рдЗрдирд▓рд╛рдЗрди рд╣реЛрддреА рд╣реИред рдпрд╣ рдПрдХ рдЕрдЪреНрдЫрд╛ рдЕрдиреБрдХреВрд▓рди рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХрд╛ рдХрд╛рд░рдг рдмрди рд╕рдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдпрдХреНрд░рдо рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:

class Program
{
    private static ManualResetEventSlim _mutex = new ManualResetEventSlim();
    
    public static async Task Deadlock()
    {
        await ProcessAsync();
        _mutex.Wait();
    }
    
    private static Task ProcessAsync()
    {
        var tcs = new TaskCompletionSource<bool>();
        
        Task.Run(() =>
        {
            Thread.Sleep(2000); //  - 
            tcs.SetResult(true);
            _mutex.Set();
        });
        
        return tcs.Task;
    }
    
    static void Main(string[] args)
    {
        Deadlock().Wait();
        Console.WriteLine("Will never get there");
    }
}

рдХреЙрд▓ рд╡рд░реНрддрдорд╛рди рдереНрд░реЗрдб рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрди tcs.SetResultрдХреЛ рдЬрд╛рд░реА рд░рдЦрдиреЗ await ProcessAsync()рдХрд╛ рдХрд╛рд░рдг рдмрдирддрд╛ рд╣реИ ред рдЗрд╕рд▓рд┐рдП, рдХрдерди _mutex.Wait()рдХреЛ рдЙрд╕реА рдереНрд░реЗрдб рджреНрд╡рд╛рд░рд╛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдЗрд╕реЗ рдХреЙрд▓ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП _mutex.Set(), рдЬрд┐рд╕рд╕реЗ рдЧрддрд┐рд░реЛрдз рд╣реЛрддрд╛ рд╣реИред рдкреИрд░рд╛рдореАрдЯрд░ TaskCreationsOptions.RunContinuationsAsynchronouslyрд╕реА рдкрд╛рд╕ рдХрд░рдХреЗ рдЗрд╕рд╕реЗ рдмрдЪрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ TaskCompletionSourceред

рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдЗрд╕реЗ рдЙрдкреЗрдХреНрд╖рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдЕрдЪреНрдЫрд╛ рдХрд╛рд░рдг рдирд╣реАрдВ рд╣реИ, TaskCreationsOptions.RunContinuationsAsynchronouslyрддреЛ рдмрдирд╛рддреЗ рд╕рдордп рд╣рдореЗрд╢рд╛ рд╡рд┐рдХрд▓реНрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ TaskCompletionSourceред

рд╕рд╛рд╡рдзрд╛рди рд░рд╣реЗрдВ: рдпрджрд┐ рдЖрдк TaskContinuationOptions.RunContinuationsAsynchronouslyрдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдХреЛрдб рднреА рд╕рдВрдХрд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ TaskCreationOptions.RunContinuationsAsynchronously, рд▓реЗрдХрд┐рди рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рдЕрдирджреЗрдЦреА рдХреА рдЬрд╛рдПрдЧреА, рдФрд░ рдирд┐рд░рдВрддрд░рддрд╛ рдЕрднреА рднреА рдЗрдирд▓рд╛рдЗрди рд╣реЛрдЧреАред рдпрд╣ рдЖрд╢реНрдЪрд░реНрдпрдЬрдирдХ рд░реВрдк рд╕реЗ рд╕рд╛рдорд╛рдиреНрдп рдЧрд▓рддреА рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╕реНрд╡рддрдГ рдкреВрд░реНрдг TaskContinuationOptionsрд╣реЛрддреА рд╣реИ TaskCreationOptionsред

Task.Run / Task.Factory.StartNew


рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдХрд╛рд░рдг рдирд╣реАрдВ рд╣реИ Task.Factory.StartNew, рддреЛ рд╣рдореЗрд╢рд╛ Task.RunрдкреГрд╖реНрдарднреВрдорд┐ рдХрд╛рд░реНрдп рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЪреБрдиреЗрдВ ред Task.Runрдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рд╕реЗ рднреА рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рд▓реМрдЯрд╛рдП рдЧрдП рдХрд╛рд░реНрдп рдХреЛ рдЕрдирдкреИрдХ рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдЕрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рддрд░реАрдХреЛрдВ рдХреЗ рд╕рд╛рде рдЕрд╕рдВрдмрджреНрдз рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рд░реЛрдХрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдпрдХреНрд░рдо рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:

class Program
{
    public static async Task ProcessAsync()
    {
        await Task.Delay(2000);
        Console.WriteLine("Processing done");
    }
    
    static async Task Main(string[] args)
    {
        await Task.Factory.StartNew(ProcessAsync);
        Console.WriteLine("End of program");
        Console.ReadLine();
    }
}

рдЗрд╕рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛ рдЕрдВрдд рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХрд┐рдП рдЬрд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдРрд╕рд╛ рдЗрд╕рд▓рд┐рдП рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ Task.Factory.StartNewрд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдЧрд╛ Task<Task>, рдФрд░ рдХреЛрдб рдХреЗрд╡рд▓ рдПрдХ рдмрд╛рд╣рд░реА рдХрд╛рд░реНрдп рдХреА рдЙрдореНрдореАрдж рдХрд░рддрд╛ рд╣реИред рд╕рд╣реА рдХреЛрдб await Task.Factory.StartNew(ProcessAsync).Unwrap()рдпрд╛ рддреЛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ , рдпрд╛ await Task.Run(ProcessAsync)ред

рдХреЗрд╡рд▓ рддреАрди рд╡реИрдз рдЙрдкрдпреЛрдЧ рдорд╛рдорд▓реЗ рд╣реИрдВ Task.Factory.StartNew:

  • рдХрд┐рд╕реА рдЕрдиреНрдп рд╢реЗрдбреНрдпреВрд▓рд░ рдореЗрдВ рдХреЛрдИ рдХрд╛рд░реНрдп рдЪрд▓рд╛рдирд╛ред
  • рдПрдХ рд╕рдорд░реНрдкрд┐рдд рдзрд╛рдЧреЗ рдореЗрдВ рдПрдХ рдХрд╛рд░реНрдп рдХрд░рдирд╛ (рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ TaskCreationOptions.LongRunning)ред
  • ( TaskCreationOptions.PreferFairness).



.



All Articles