рд╡реЗрд▓-рдлреЗрдб рдлрд┐рд▓реЙрд╕реЙрдлрд░ рдХрд┐рдВрд╡рд╛ рд╕реНрдкрд░реНрдзрд╛рддреНрдордХ .NET рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ

рд╡реЗрд▓-рдлреЗрдб рдлрд┐рд▓реЙрд╕реЙрдлрд░ рдХрд┐рдВрд╡рд╛ рд╕реНрдкрд░реНрдзрд╛рддреНрдордХ .NET рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ

рдЙрджрд╛рд╣рд░рдг рдореНрд╣рдгреВрди рдлрд┐рд▓реЙрд╕реЙрдлрд░реНрд╕ рдбрд╛рдпрдирд┐рдВрдЧ рдкреНрд░реЙрдмреНрд▓реЗрдо рд╡рд╛рдкрд░реВрди .Net рдордзреНрдпреЗ рд╕рдорд╡рд░реНрддреА рдЖрдгрд┐ рд╕рдорд╛рдВрддрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХрд╕реЗ рдХрд╛рд░реНрдп рдХрд░рддреЗ рддреЗ рдкрд╛рд╣реВ. рдпреЛрдЬрдирд╛ рдЕрд╢реА рдЖрд╣реЗ, рдереНрд░реЗрдбреНрд╕/рдкреНрд░реЛрд╕реЗрд╕рдЪреНрдпрд╛ рд╕рд┐рдВрдХреНрд░реЛрдирд╛рдЗрдЭреЗрд╢рдирдкрд╛рд╕реВрди рддреЗ рдЕрднрд┐рдиреЗрддрд╛ рдореЙрдбреЗрд▓рдкрд░реНрдпрдВрдд (рдкреБрдвреАрд▓ рднрд╛рдЧрд╛рдВрдордзреНрдпреЗ). рд▓реЗрдЦ рдкрд╣рд┐рд▓реНрдпрд╛ рдУрд│рдЦреАрд╕рд╛рдареА рдХрд┐рдВрд╡рд╛ рдЖрдкрд▓реЗ рдЬреНрдЮрд╛рди рддрд╛рдЬреЗрддрд╡рд╛рдиреЗ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдЙрдкрдпреБрдХреНрдд рдЕрд╕реВ рд╢рдХрддреЛ.

рд╣реЗ рдЕрдЬрд┐рдмрд╛рдд рдХрд╛ рдХрд░рд╛рдпрдЪреЗ? рдЯреНрд░рд╛рдиреНрдЭрд┐рд╕реНрдЯрд░ рддреНрдпрд╛рдВрдЪреНрдпрд╛ рдХрд┐рдорд╛рди рдЖрдХрд╛рд░рд╛рдкрд░реНрдпрдВрдд рдкреЛрд╣реЛрдЪрддрд╛рдд, рдореВрд░рдЪрд╛ рдирд┐рдпрдо рдкреНрд░рдХрд╛рд╢рд╛рдЪреНрдпрд╛ рд╡реЗрдЧрд╛рдЪреНрдпрд╛ рдорд░реНрдпрд╛рджреЗрд╡рд░ рдЕрд╡рд▓рдВрдмреВрди рдЕрд╕рддреЛ рдЖрдгрд┐ рдореНрд╣рдгреВрди рд╕рдВрдЦреНрдпреЗрдд рд╡рд╛рдв рджрд┐рд╕реВрди рдпреЗрддреЗ, рдЕрдзрд┐рдХ рдЯреНрд░рд╛рдиреНрдЭрд┐рд╕реНрдЯрд░ рдмрдирд╡рддрд╛ рдпреЗрддрд╛рдд. рддреНрдпрд╛рдЪ рд╡реЗрд│реА, рдбреЗрдЯрд╛рдЪреЗ рдкреНрд░рдорд╛рдг рд╡рд╛рдврдд рдЖрд╣реЗ рдЖрдгрд┐ рд╡рд╛рдкрд░рдХрд░реНрддреНрдпрд╛рдВрдирд╛ рд╕рд┐рд╕реНрдЯрдордХрдбреВрди рддреНрд╡рд░рд┐рдд рдкреНрд░рддрд┐рд╕рд╛рджрд╛рдЪреА рдЕрдкреЗрдХреНрд╖рд╛ рдЖрд╣реЗ. рдЕрд╢рд╛ рдкрд░рд┐рд╕реНрдерд┐рддреАрдд, "рд╕рд╛рдорд╛рдиреНрдп" рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ, рдЬреЗрд╡реНрд╣рд╛ рдЖрдордЪреНрдпрд╛рдХрдбреЗ рдПрдХ рдПрдХреНрдЭрд┐рдХреНрдпреВрдЯрд┐рдВрдЧ рдереНрд░реЗрдб рдЕрд╕рддреЛ, рддреЗ рдпрд╛рдкреБрдвреЗ рдкреНрд░рднрд╛рд╡реА рдирд╛рд╣реА. рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рдПрдХрд╛рдЪ рд╡реЗрд│реА рдХрд┐рдВрд╡рд╛ рд╕рдорд╡рд░реНрддреА рдЕрдВрдорд▓рдмрдЬрд╛рд╡рдгреАрдЪреА рд╕рдорд╕реНрдпрд╛ рдХрд╢реА рддрд░реА рд╕реЛрдбрд╡рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ. рд╢рд┐рд╡рд╛рдп, рд╣реА рд╕рдорд╕реНрдпрд╛ рд╡реЗрдЧрд╡реЗрдЧрд│реНрдпрд╛ рд╕реНрддрд░рд╛рдВрд╡рд░ рдЕрд╕реНрддрд┐рддреНрд╡рд╛рдд рдЖрд╣реЗ: рдереНрд░реЗрдбреНрд╕рдЪреНрдпрд╛ рдкрд╛рддрд│реАрд╡рд░, рдкреНрд░рдХреНрд░рд┐рдпреЗрдЪреНрдпрд╛ рдкрд╛рддрд│реАрд╡рд░, рдиреЗрдЯрд╡рд░реНрдХрдордзреАрд▓ рдорд╢реАрдиреНрд╕рдЪреНрдпрд╛ рдкрд╛рддрд│реАрд╡рд░ (рд╡рд┐рддрд░рд┐рдд рд╕рд┐рд╕реНрдЯрдо). рдЕрд╢рд╛ рд╕рдорд╕реНрдпрд╛ рдЬрд▓рдж рдЖрдгрд┐ рдХрд╛рд░реНрдпрдХреНрд╖рдорддреЗрдиреЗ рд╕реЛрдбрд╡рдгреНрдпрд╛рд╕рд╛рдареА .NET рдХрдбреЗ рдЙрдЪреНрдЪ-рдЧреБрдгрд╡рддреНрддреЗрдЪреЗ, рд╡реЗрд│-рдЪрд╛рдЪрдгреА рддрдВрддреНрд░рдЬреНрдЮрд╛рди рдЖрд╣реЗ.

рдЙрджреНрджрд┐рд╖реНрдЯ

рдПрдбреНрд╕рдЧрд░ рдбрд┐рдЬрдХреНрд╕реНрдЯреНрд░рд╛рдиреЗ рд╣реА рд╕рдорд╕реНрдпрд╛ 1965 рдЪреНрдпрд╛ рд╕реБрд░реБрд╡рд╛рддреАрдкрд╛рд╕реВрдирдЪ рддреНрдпрд╛рдВрдЪреНрдпрд╛ рд╡рд┐рджреНрдпрд╛рд░реНрдереНрдпрд╛рдВрд╕рдореЛрд░ рдорд╛рдВрдбрд▓реА. рд╕реНрдерд╛рдкрди рдХреЗрд▓реЗрд▓реА рд╕реВрддреНрд░реЗ рдЦрд╛рд▓реАрд▓рдкреНрд░рдорд╛рдгреЗ рдЖрд╣реЗ. рддрддреНрддреНрд╡рд╡реЗрддреНрддреНрдпрд╛рдВрдЪреА рдард░рд╛рд╡рд┐рдХ (рд╕рд╛рдорд╛рдиреНрдпрдд: рдкрд╛рдЪ) рд╕рдВрдЦреНрдпрд╛ рдЕрд╕рддреЗ рдЖрдгрд┐ рддреЗрд╡рдвреАрдЪ рдХрд╛рдЯреЗ рдЕрд╕рддрд╛рдд. рддреЗ рдПрдХрд╛ рдЧреЛрд▓ рдЯреЗрдмрд▓рд╛рд╡рд░ рдмрд╕рддрд╛рдд, рддреНрдпрд╛рдВрдЪреНрдпрд╛рдордзреНрдпреЗ рдХрд╛рдЯреЗ рдЕрд╕рддрд╛рдд. рддрддреНрд╡рдЬреНрдЮрд╛рдиреА рддреНрдпрд╛рдВрдЪреНрдпрд╛ рддрд╛рдЯрд╛рддреВрди рдЕрдВрддрд╣реАрди рдЕрдиреНрди рдЦрд╛рдК рд╢рдХрддрд╛рдд, рд╡рд┐рдЪрд╛рд░ рдХрд░реВ рд╢рдХрддрд╛рдд рдХрд┐рдВрд╡рд╛ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реВ рд╢рдХрддрд╛рдд. рддрддреНрд╡рдЬреНрдЮрд╛рдиреА рдЦрд╛рдгреНрдпрд╛рд╕рд╛рдареА, рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рджреЛрди рдХрд╛рдЯреЗ рдШреЗрдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ (рд╢реЗрд╡рдЯрдЪрд╛ рдХрд╛рдЯрд╛ рдкрд╣рд┐рд▓реНрдпрд╛рд╕рд╣ рд╕рд╛рдорд╛рдпрд┐рдХ рдХрд░рддреЛ). рдХрд╛рдЯрд╛ рдЙрдЪрд▓рдгреЗ рдЖрдгрд┐ рдЦрд╛рд▓реА рдареЗрд╡рдгреЗ рдпрд╛ рджреЛрди рд╕реНрд╡рддрдВрддреНрд░ рдХреНрд░рд┐рдпрд╛ рдЖрд╣реЗрдд. рд╕рд░реНрд╡ рддрддреНрддреНрд╡рдЬреНрдЮ рдЧрдкреНрдк рдЖрд╣реЗрдд. рдХрд╛рд░реНрдп рдЕрд╕рд╛ рдЕрд▓реНрдЧреЛрд░рд┐рджрдо рд╢реЛрдзрдгреЗ рдЖрд╣реЗ рдХреА рддреЗ рд╕рд░реНрд╡ рд╡рд┐рдЪрд╛рд░ рдХрд░рддреАрд▓ рдЖрдгрд┐ 54 рд╡рд░реНрд╖рд╛рдВрдирдВрддрд░рд╣реА рдкрд░рд┐рдкреВрд░реНрдг рдЕрд╕рддреАрд▓.

рдкреНрд░рдердо, рд╕рд╛рдорд╛рдпрд┐рдХ рдХреЗрд▓реЗрд▓реНрдпрд╛ рдЬрд╛рдЧреЗрдЪреНрдпрд╛ рд╡рд╛рдкрд░рд╛рджреНрд╡рд╛рд░реЗ рдпрд╛ рд╕рдорд╕реНрдпреЗрдЪреЗ рдирд┐рд░рд╛рдХрд░рдг рдХрд░рдгреНрдпрд╛рдЪрд╛ рдкреНрд░рдпрддреНрди рдХрд░реВрдпрд╛. рдХрд╛рдЯреЗ рд╕рд╛рдорд╛рдиреНрдп рдЯреЗрдмрд▓рд╛рд╡рд░ рдкрдбрд▓реЗрд▓реЗ рдЕрд╕рддрд╛рдд рдЖрдгрд┐ рддрддреНрд╡рдЬреНрдЮрд╛рдиреА рддреЗ рдЕрд╕рддрд╛рдд рддреЗрд╡реНрд╣рд╛ рддреЗ рдШреЗрддрд╛рдд рдЖрдгрд┐ рдкрд░рдд рдареЗрд╡рддрд╛рдд. рдпреЗрдереЗ рд╕рд┐рдВрдХреНрд░реЛрдирд╛рдЗрдЭреЗрд╢рдирдордзреНрдпреЗ рд╕рдорд╕реНрдпрд╛ рдЖрд╣реЗрдд, рдирдХреНрдХреА рдХреЗрд╡реНрд╣рд╛ рдШреНрдпрд╛рдпрдЪреЗ? рдХрд╛рдЯрд╛ рдирд╕реЗрд▓ рддрд░ рдХрд╛рдп? рдЗ. рдкрдг рдкреНрд░рдердо, рддрддреНрддреНрд╡рдЬреНрдЮ рд╕реБрд░реВ рдХрд░реВрдпрд╛.

рдереНрд░реЗрдбреНрд╕ рд╕реБрд░реВ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА, рдЖрдореНрд╣реА рдереНрд░реЗрдб рдкреВрд▓ рд╡рд╛рдкрд░рддреЛ Task.Run рдкрджреНрдзрдд:

var cancelTokenSource = new CancellationTokenSource();
Action<int> create = (i) => RunPhilosopher(i, cancelTokenSource.Token);
for (int i = 0; i < philosophersAmount; i++) 
{
    int icopy = i;
    // ╨Я╨╛╨╝╨╡╤Б╤В╨╕╤В╤М ╨╖╨░╨┤╨░╤З╤Г ╨▓ ╨╛╤З╨╡╤А╨╡╨┤╤М ╨┐╤Г╨╗╨░ ╨┐╨╛╤В╨╛╨║╨╛╨▓. ╨Ь╨╡╤В╨╛╨┤ RunDeadlock ╨╜╨╡ ╨╖╨░╨┐╤Г╤Б╨║╨░╨╡╤В╤М╤Б╤П 
    // ╤Б╤А╨░╨╖╤Г, ╨░ ╨╢╨┤╨╡╤В ╤Б╨▓╨╛╨╡╨│╨╛ ╨┐╨╛╤В╨╛╨║╨░. ╨Р╤Б╨╕╨╜╤Е╤А╨╛╨╜╨╜╤Л╨╣ ╨╖╨░╨┐╤Г╤Б╨║.
    philosophers[i] = Task.Run(() => create(icopy), cancelTokenSource.Token);
}

рдереНрд░реЗрдб рдкреВрд▓ рдереНрд░реЗрдб рддрдпрд╛рд░ рдХрд░рдгреЗ рдЖрдгрд┐ рд╣рдЯрд╡рд┐рдгреЗ рдСрдкреНрдЯрд┐рдорд╛рдЗрдЭ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдбрд┐рдЭрд╛рдЗрди рдХреЗрд▓реЗ рдЖрд╣реЗ. рдпрд╛ рдкреВрд▓рдордзреНрдпреЗ рдХрд╛рд░реНрдпрд╛рдВрд╕рд╣ рд░рд╛рдВрдЧ рдЖрд╣реЗ рдЖрдгрд┐ рдпрд╛ рдХрд╛рд░реНрдпрд╛рдВрдЪреНрдпрд╛ рд╕рдВрдЦреНрдпреЗрд╡рд░ рдЕрд╡рд▓рдВрдмреВрди CLR рдереНрд░реЗрдб рддрдпрд╛рд░ рдХрд░рддреЗ рдХрд┐рдВрд╡рд╛ рдХрд╛рдвреВрди рдЯрд╛рдХрддреЗ. рд╕рд░реНрд╡ AppDomains рд╕рд╛рдареА рдПрдХ рдкреВрд▓. рд╣рд╛ рдкреВрд▓ рдЬрд╡рд│рдЬрд╡рд│ рдиреЗрд╣рдореАрдЪ рд╡рд╛рдкрд░рд▓рд╛ рдкрд╛рд╣рд┐рдЬреЗ, рдХрд╛рд░рдг. рдереНрд░реЗрдбреНрд╕ рддрдпрд╛рд░ рдХрд░рдгреЗ, рд╣рдЯрд╡рдгреЗ, рддреНрдпрд╛рдВрдЪреНрдпрд╛ рд░рд╛рдВрдЧрд╛ рдЗрддреНрдпрд╛рджреАрдВрдЪрд╛ рддреНрд░рд╛рд╕ рдХрд░рдгреНрдпрд╛рдЪреА рдЧрд░рдЬ рдирд╛рд╣реА. рд╣реЗ рдкреВрд▓рд╢рд┐рд╡рд╛рдп рд╢рдХреНрдп рдЖрд╣реЗ, рдкрд░рдВрддреБ рдирдВрддрд░ рддреБрдореНрд╣рд╛рд▓рд╛ рддреЗ рдереЗрдЯ рд╡рд╛рдкрд░рд╛рд╡реЗ рд▓рд╛рдЧреЗрд▓ Thread, рд╣реЗ рдЕрд╢рд╛ рдкреНрд░рдХрд░рдгрд╛рдВрд╕рд╛рдареА рдЙрдкрдпреБрдХреНрдд рдЖрд╣реЗ рдЬреЗрд╡реНрд╣рд╛ рддреБрдореНрд╣рд╛рд▓рд╛ рдереНрд░реЗрдбрдЪрд╛ рдкреНрд░рд╛рдзрд╛рдиреНрдпрдХреНрд░рдо рдмрджрд▓рдгреНрдпрд╛рдЪреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЕрд╕рддреЗ, рдЬреЗрд╡реНрд╣рд╛ рдЖрдордЪреНрдпрд╛рдХрдбреЗ рджреАрд░реНрдШ рдСрдкрд░реЗрд╢рди рдЕрд╕рддреЗ, рдлреЛрд░рдЧреНрд░рд╛рдЙрдВрдб рдереНрд░реЗрдб рдЗрддреНрдпрд╛рджреАрд╕рд╛рдареА.

рджреБрд╕рд░рд╝реНрдпрд╛ рд╢рдмреНрджрд╛рдд, System.Threading.Tasks.Task рд╡рд░реНрдЧ рд╕рдорд╛рди рдЖрд╣реЗ Thread, рдкрд░рдВрддреБ рд╕рд░реНрд╡ рдкреНрд░рдХрд╛рд░рдЪреНрдпрд╛ рд╕реЛрдпреАрдВрд╕рд╣: рдЗрддрд░ рдХрд╛рд░реНрдпрд╛рдВрдЪреНрдпрд╛ рдмреНрд▓реЙрдХрдирдВрддрд░ рдХрд╛рд░реНрдп рдЪрд╛рд▓рд╡рд┐рдгреНрдпрд╛рдЪреА рдХреНрд╖рдорддрд╛, рддреНрдпрд╛рдВрдирд╛ рдХрд╛рд░реНрдпрд╛рдВрдордзреВрди рдкрд░рдд рдХрд░рдгреЗ, рддреНрдпрд╛рдВрдирд╛ рд╕реЛрдпреАрд╕реНрдХрд░рдкрдгреЗ рд╡реНрдпрддреНрдпрдп рдЖрдгрдгреЗ рдЖрдгрд┐ рдмрд░реЗрдЪ рдХрд╛рд╣реА. рдЗ. рддреЗ async / рдкреНрд░рддреАрдХреНрд╖рд╛ рдмрд╛рдВрдзрдХрд╛рдорд╛рдВрдирд╛ рд╕рдорд░реНрдерди рджреЗрдгреНрдпрд╛рд╕рд╛рдареА рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗрдд (рдХрд╛рд░реНрдп-рдЖрдзрд╛рд░рд┐рдд рдЕрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдкреЕрдЯрд░реНрди, IO рдСрдкрд░реЗрд╢рдиреНрд╕рдЪреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рд╕рд┐рдВрдЯреЕрдХреНрдЯрд┐рдХ рд╢реБрдЧрд░). рдЖрдореНрд╣реА рдпрд╛рдмрджреНрджрд▓ рдЕрдзрд┐рдХ рдмреЛрд▓реВ.

CancelationTokenSource рдпреЗрдереЗ рддреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ рдЬреЗрдгреЗрдХрд░реВрди рдереНрд░реЗрдб рдХреЙрд▓рд┐рдВрдЧ рдереНрд░реЗрдбрдЪреНрдпрд╛ рд╕рд┐рдЧреНрдирд▓рд╡рд░ рд╕реНрд╡рддрдГрд▓рд╛ рд╕рдВрдкреБрд╖реНрдЯрд╛рдд рдЖрдгреВ рд╢рдХреЗрд▓.

рд╕рдордХреНрд░рдордг рд╕рдорд╕реНрдпрд╛

рдЕрд╡рд░реЛрдзрд┐рдд рддрддреНрддреНрд╡рдЬреНрдЮ

рдареАрдХ рдЖрд╣реЗ, рдЖрдореНрд╣рд╛рд▓рд╛ рдереНрд░реЗрдб рдХрд╕реЗ рддрдпрд╛рд░ рдХрд░рд╛рдпрдЪреЗ рд╣реЗ рдорд╛рд╣рд┐рдд рдЖрд╣реЗ, рдЪрд▓рд╛ рджреБрдкрд╛рд░рдЪреЗ рдЬреЗрд╡рдг рдХрд░рдгреНрдпрд╛рдЪрд╛ рдкреНрд░рдпрддреНрди рдХрд░реВрдпрд╛:

// ╨Ъ╤В╨╛ ╨║╨░╨║╨╕╨╡ ╨▓╨╕╨╗╨║╨╕ ╨▓╨╖╤П╨╗. ╨Ъ ╨┐╤А╨╕╨╝╨╡╤А╤Г: 1 1 3 3 - 1╨╣ ╨╕ 3╨╣ ╨▓╨╖╤П╨╗╨╕ ╨┐╨╡╤А╨▓╤Л╨╡ ╨┤╨▓╨╡ ╨┐╨░╤А╤Л.
private int[] forks = Enumerable.Repeat(0, philosophersAmount).ToArray();

// ╨в╨╛ ╨╢╨╡, ╤З╤В╨╛ RunPhilosopher()
private void RunDeadlock(int i, CancellationToken token) 
{
    // ╨Ц╨┤╨░╤В╤М ╨▓╨╕╨╗╨║╤Г, ╨▓╨╖╤П╤В╤М ╨╡╤С. ╨н╨║╨▓╨╕╨▓╨░╨╗╨╡╨╜╤В╨╜╨╛: 
    // while(true) 
    //     if forks[fork] == 0 
    //          forks[fork] = i+1
    //          break
    //     Thread.Sleep() ╨╕╨╗╨╕ Yield() ╨╕╨╗╨╕ SpinWait()
    void TakeFork(int fork) =>
        SpinWait.SpinUntil(() => 
            Interlocked.CompareExchange(ref forks[fork], i+1, 0) == 0);

    // ╨Ф╨╗╤П ╨┐╤А╨╛╤Б╤В╨╛╤В╤Л, ╨╜╨╛ ╨╝╨╛╨╢╨╜╨╛ ╤Б Interlocked.Exchange:
    void PutFork(int fork) => forks[fork] = 0;

    while (true)
    {
        TakeFork(Left(i));
        TakeFork(Right(i));
        eatenFood[i] = (eatenFood[i] + 1) % (int.MaxValue - 1);
        PutFork(Left(i));
        PutFork(Right(i));
        Think(i);

        // ╨Ч╨░╨▓╨╡╤А╤И╨╕╤В╤М ╤А╨░╨▒╨╛╤В╤Г ╨┐╨╛-╤Е╨╛╤А╨╛╤И╨╡╨╝╤Г.
        token.ThrowIfCancellationRequested();
    }
}

рдпреЗрдереЗ рдЖрдкрдг рдкреНрд░рдердо рдбрд╛рд╡рд╛ рдХрд╛рдЯрд╛ рдЖрдгрд┐ рдирдВрддрд░ рдЙрдЬрд╡рд╛ рдХрд╛рдЯрд╛ рдШреЗрдгреНрдпрд╛рдЪрд╛ рдкреНрд░рдпрддреНрди рдХрд░рддреЛ, рдЖрдгрд┐ рдЬрд░ рддреЗ рдХрд╛рд░реНрдп рдХрд░рдд рдЕрд╕реЗрд▓ рддрд░ рдЖрдкрдг рддреЗ рдЦрд╛рддреЛ рдЖрдгрд┐ рдкрд░рдд рдареЗрд╡рддреЛ. рдПрдХ рдХрд╛рдЯрд╛ рдШреЗрдгреЗ рдЕрдгреВ рдЖрд╣реЗ, рдореНрд╣рдгрдЬреЗ. рджреЛрди рдзрд╛рдЧреЗ рдПрдХрд╛рдЪ рд╡реЗрд│реА рдПрдХ рдШреЗрдК рд╢рдХрдд рдирд╛рд╣реАрдд (рдЕрдпреЛрдЧреНрдп: рдкреНрд░рдердо рд╡рд╛рдЪрддреЛ рдХреА рдХрд╛рдЯрд╛ рд╡рд┐рдирд╛рдореВрд▓реНрдп рдЖрд╣реЗ, рджреБрд╕рд░рд╛ - рдЦреВрдк, рдкрд╣рд┐рд▓рд╛ рдШреЗрддреЛ, рджреБрд╕рд░рд╛ рдШреЗрддреЛ). рдпрд╛рд╕рд╛рдареА рдПрд╕ Interlocked.CompareExchange, рдЬреНрдпрд╛рдЪреА рдЕрдВрдорд▓рдмрдЬрд╛рд╡рдгреА рдкреНрд░реЛрд╕реЗрд╕рд░ рдирд┐рд░реНрджреЗрд╢рд╛рдВрд╕рд╣ рдХрд░рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ (TSL, XCHG), рдЬреЗ рдЕрдгреВ рдЕрдиреБрдХреНрд░рдорд┐рдХ рд╡рд╛рдЪрди рдЖрдгрд┐ рд▓реЗрдЦрдирд╛рд╕рд╛рдареА рдореЗрдорд░реАрдЪрд╛ рддреБрдХрдбрд╛ рд▓реЙрдХ рдХрд░рддреЗ. рдЖрдгрд┐ SpinWait рд░рдЪрдирд╛ рд╕рдорддреБрд▓реНрдп рдЖрд╣реЗ while(true) рдлрдХреНрдд рдереЛрдбреНрдпрд╛ "рдЬрд╛рджреВ" рд╕рд╣ - рдереНрд░реЗрдб рдкреНрд░реЛрд╕реЗрд╕рд░ рдШреЗрддреЛ (Thread.SpinWait), рдкрд░рдВрддреБ рдХрдзреАрдХрдзреА рдирд┐рдпрдВрддреНрд░рдг рджреБрд╕рд░реНрдпрд╛ рдереНрд░реЗрдбрд╡рд░ рд╣рд╕реНрддрд╛рдВрддрд░рд┐рдд рдХрд░рддреЗ (Thread.Yeild) рдХрд┐рдВрд╡рд╛ рдЭреЛрдкреА рдЬрд╛рддреЛ (Thread.Sleep).

рдкрдг рд╣рд╛ рдЙрдкрд╛рдп рдХрд╛рдо рдХрд░рдд рдирд╛рд╣реА, рдХрд╛рд░рдг рдкреНрд░рд╡рд╛рд╣ рд▓рд╡рдХрд░рдЪ (рдорд╛рдЭреНрдпрд╛рд╕рд╛рдареА рдПрдХрд╛ рд╕реЗрдХрдВрджрд╛рдд) рдЕрд╡рд░реЛрдзрд┐рдд рдХреЗрд▓реЗ рдЬрд╛рддрд╛рдд: рд╕рд░реНрд╡ рддрддреНрддреНрд╡рдЬреНрдЮ рддреНрдпрд╛рдВрдЪрд╛ рдбрд╛рд╡рд╛ рдХрд╛рдЯрд╛ рдШреЗрддрд╛рдд, рдкрд░рдВрддреБ рдЙрдЬрд╡рд╛ рдирд╛рд╣реА. рдлреЙрд░реНрдХреНрд╕ рдЕреЕрд░реЗрдордзреНрдпреЗ рдореВрд▓реНрдпреЗ рдЖрд╣реЗрдд: 1 2 3 4 5.

рд╡реЗрд▓-рдлреЗрдб рдлрд┐рд▓реЙрд╕реЙрдлрд░ рдХрд┐рдВрд╡рд╛ рд╕реНрдкрд░реНрдзрд╛рддреНрдордХ .NET рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ

рдЖрдХреГрддреАрдордзреНрдпреЗ, рдереНрд░реЗрдб рдЕрд╡рд░реЛрдзрд┐рдд рдХрд░рдгреЗ (рдбреЗрдбрд▓реЙрдХ). рд╣рд┐рд░рд╡рд╛ - рдЕрдВрдорд▓рдмрдЬрд╛рд╡рдгреА, рд▓рд╛рд▓ - рд╕рд┐рдВрдХреНрд░реЛрдирд╛рдЗрдЭреЗрд╢рди, рд░рд╛рдЦрд╛рдбреА - рдзрд╛рдЧрд╛ рдЭреЛрдкрдд рдЖрд╣реЗ. рд╕рдорднреБрдЬ рдЪреМрдХреЛрди рдХрд╛рд░реНрдпреЗ рд╕реБрд░реВ рд╣реЛрдгреНрдпрд╛рдЪреА рд╡реЗрд│ рджрд░реНрд╢рд╡рддрд╛рдд.

рддрддреНрддреНрд╡рдЬреНрдЮрд╛рдВрдЪреА рднреВрдХ

рдЬрд░реА рд╡рд┐рд╢реЗрд╖рддрдГ рдЬрд╛рд╕реНрдд рдЕрдиреНрдирд╛рдЪрд╛ рд╡рд┐рдЪрд╛рд░ рдХрд░рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдирд╛рд╣реА, рдкрд░рдВрддреБ рднреВрдХ рдХреЛрдгрд╛рд▓рд╛рд╣реА рддрддреНрддреНрд╡рдЬреНрдЮрд╛рди рд╕реЛрдбрдгреНрдпрд╛рд╕ рдкреНрд░рд╡реГрддреНрдд рдХрд░рддреЗ. рдЪрд▓рд╛ рдЖрдкрд▓реНрдпрд╛ рд╕рдорд╕реНрдпреЗрддреАрд▓ рдереНрд░реЗрдбреНрд╕рдЪреНрдпрд╛ рдЙрдкрд╛рд╕рдорд╛рд░реАрдЪреНрдпрд╛ рдкрд░рд┐рд╕реНрдерд┐рддреАрдЪреЗ рдЕрдиреБрдХрд░рдг рдХрд░рдгреНрдпрд╛рдЪрд╛ рдкреНрд░рдпрддреНрди рдХрд░реВрдпрд╛. рдЙрдкрд╛рд╕рдорд╛рд░ рдореНрд╣рдгрдЬреЗ рдЬреЗрд╡реНрд╣рд╛ рдПрдЦрд╛рджрд╛ рдзрд╛рдЧрд╛ рдЪрд╛рд▓реВ рдЕрд╕рддреЛ, рдкрд░рдВрддреБ рдорд╣рддреНрддреНрд╡рдкреВрд░реНрдг рдХрд╛рдо рди рдХрд░рддрд╛, рджреБрд╕рд▒реНрдпрд╛ рд╢рдмреНрджрд╛рдВрдд, рд╣реЗ рд╕рдорд╛рди рдЧрддрд┐рд░реЛрдз рдЖрд╣реЗ, рдлрдХреНрдд рдЖрддрд╛ рдзрд╛рдЧрд╛ рдЭреЛрдкрдд рдирд╛рд╣реА, рдкрд░рдВрддреБ рд╕рдХреНрд░рд┐рдпрдкрдгреЗ рдХрд╛рд╣реАрддрд░реА рдЦрд╛рдгреНрдпрд╛рд╕рд╛рдареА рд╢реЛрдзрдд рдЖрд╣реЗ, рдкрд░рдВрддреБ рдЕрдиреНрди рдирд╛рд╣реА. рд╡рд╛рд░рдВрд╡рд╛рд░ рдмреНрд▓реЙрдХ рд╣реЛрдК рдирдпреЗ рдореНрд╣рдгреВрди, рдЬрд░ рдЖрдореНрд╣рд╛рд▓рд╛ рджреБрд╕рд░рд╛ рдХрд╛рдЯрд╛ рдШреЗрддрд╛ рдЖрд▓рд╛ рдирд╛рд╣реА рддрд░ рдЖрдореНрд╣реА рдХрд╛рдЯрд╛ рдкрд░рдд рдареЗрд╡реВ.

// ╨в╨╛ ╨╢╨╡ ╤З╤В╨╛ ╨╕ ╨▓ RunDeadlock, ╨╜╨╛ ╤В╨╡╨┐╨╡╤А╤М ╨║╨╗╨░╨┤╨╡╨╝ ╨▓╨╕╨╗╨║╤Г ╨╜╨░╨╖╨░╨┤ ╨╕ ╨┤╨╛╨▒╨░╨▓╨╗╤П╨╡╨╝ ╨┐╨╗╨╛╤Е╨╕╤Е ╤Д╨╕╨╗╨╛╤Б╨╛╤Д╨╛╨▓.
private void RunStarvation(int i, CancellationToken token)
{
    while (true)
    {
        bool hasTwoForks = false;
        var waitTime = TimeSpan.FromMilliseconds(50);
        // ╨Я╨╗╨╛╤Е╨╛╨╣ ╤Д╨╕╨╗╨╛╤Б╨╛╤Д╨╛╨▓ ╨╝╨╛╨╢╨╡╤В ╤Г╨╢╨╡ ╨╕╨╝╨╡╤В╤М ╨▓╨╕╨╗╨║╤Г:
        bool hasLeft = forks[Left(i)] == i + 1;
        if (hasLeft || TakeFork(Left(i), i + 1, waitTime))
        {
            if (TakeFork(Right(i), i + 1, TimeSpan.Zero))
                hasTwoForks = true;
            else
                PutFork(Left(i)); // ╨Ш╨╜╨╛╨│╨┤╨░ ╨┐╨╗╨╛╤Е╨╛╨╣ ╤Д╨╕╨╗╨╛╤Б╨╛╤Д ╨╛╤В╨┤╨░╨╡╤В ╨▓╨╕╨╗╨║╤Г ╨╜╨░╨╖╨░╨┤.
        } 
        if (!hasTwoForks)
        {
            if (token.IsCancellationRequested) break;
            continue;
        }
        eatenFood[i] = (eatenFood[i] + 1) % (int.MaxValue - 1);
        bool goodPhilosopher = i % 2 == 0;
        // ╨Р ╨┐╨╗╨╛╤Е╨╛╨╣ ╤Д╨╕╨╗╨╛╤Б╨╛╤Д ╨╖╨░╨▒╤Л╨▓╨░╨╡╤В ╨┐╨╛╨╗╨╛╨╢╨╕╤В╤М ╤Б╨▓╨╛╤О ╨▓╨╕╨╗╨║╤Г ╨╛╨▒╤А╨░╤В╨╜╨╛:
        if (goodPhilosopher)
            PutFork(Left(i));
        // ╨Р ╨╡╤Б╨╗╨╕ ╨╕ ╨┐╤А╨░╨▓╤Г╤О ╨╜╨╡ ╨┐╨╛╨╗╨╛╨╢╨╕╤В, ╤В╨╛ ╤Е╨╛╤А╨╛╤И╨╕╨╡ ╨▒╤Г╨┤╤Г╤В ╨▓╨╛╨╛╨▒╤Й╨╡ ╨▒╨╡╨╖ ╨╡╨┤╤Л.
        PutFork(Right(i));

        Think(i);

        if (token.IsCancellationRequested)
            break;
    }
}

// ╨в╨╡╨┐╨╡╤А╤М ╨╝╨╛╨╢╨╜╨╛ ╨╢╨┤╨░╤В╤М ╨╛╨┐╤А╨╡╨┤╨╡╨╗╨╡╨╜╨╜╨╛╨╡ ╨▓╤А╨╡╨╝╤П.
bool TakeFork(int fork, int philosopher, TimeSpan? waitTime = null)
{
    return SpinWait.SpinUntil(
        () => Interlocked.CompareExchange(ref forks[fork], philosopher, 0) == 0,
              waitTime ?? TimeSpan.FromMilliseconds(-1)
    );
}

рдпрд╛ рд╕рдВрд╣рд┐рддреЗрддреАрд▓ рдорд╣рддреНрддреНрд╡рд╛рдЪреА рдЧреЛрд╖реНрдЯ рдореНрд╣рдгрдЬреЗ рдЪрд╛рд░рдкреИрдХреА рджреЛрди рддрддреНрддреНрд╡рдЬреНрдЮ рддреНрдпрд╛рдВрдЪрд╛ рдбрд╛рд╡рд╛ рдХрд╛рдЯрд╛ рдЦрд╛рд▓реА рдареЗрд╡рд╛рдпрд▓рд╛ рд╡рд┐рд╕рд░рддрд╛рдд. рдЖрдгрд┐ рдЕрд╕реЗ рджрд┐рд╕реВрди рдЖрд▓реЗ рдХреА рддреЗ рдЕрдзрд┐рдХ рдЕрдиреНрди рдЦрд╛рддрд╛рдд, рддрд░ рдЗрддрд░рд╛рдВрдирд╛ рдЙрдкрд╛рд╢реА рд░рд╛рд╣рдгреНрдпрд╛рд╕ рд╕реБрд░реБрд╡рд╛рдд рд╣реЛрддреЗ, рдЬрд░реА рдереНрд░реЗрдбреНрд╕рдирд╛ рд╕рдорд╛рди рдкреНрд░рд╛рдзрд╛рдиреНрдп рдЕрд╕рддреЗ. рдпреЗрдереЗ рддреЗ рдкреВрд░реНрдгрдкрдгреЗ рдЙрдкрд╛рд╢реА рдирд╛рд╣реАрдд, рдХрд╛рд░рдг. рд╡рд╛рдИрдЯ рддрддреНрд╡рдЬреНрдЮрд╛рдиреА рдХрдзреА рдХрдзреА рддреНрдпрд╛рдВрдЪреЗ рдХрд╛рдЯреЗ рдорд╛рдЧреЗ рдареЗрд╡рддрд╛рдд. рдЕрд╕реЗ рджрд┐рд╕реВрди рдЖрд▓реЗ рдХреА рдЪрд╛рдВрдЧрд▓реЗ рд▓реЛрдХ рд╡рд╛рдИрдЯ рд▓реЛрдХрд╛рдВрдкреЗрдХреНрд╖рд╛ 5 рдкрдЯ рдХрдореА рдЦрд╛рддрд╛рдд. рддреНрдпрд╛рдореБрд│реЗ рдХреЛрдбрдордзреАрд▓ рд▓рд╣рд╛рди рддреНрд░реБрдЯреАрдореБрд│реЗ рдХрд╛рд░реНрдпрдкреНрд░рджрд░реНрд╢рдирд╛рдд рдШрдЯ рд╣реЛрддреЗ. рдпреЗрдереЗ рд╣реЗ рджреЗрдЦреАрд▓ рд▓рдХреНрд╖рд╛рдд рдШреЗрдгреНрдпрд╛рд╕рд╛рд░рдЦреЗ рдЖрд╣реЗ рдХреА рдПрдХ рджреБрд░реНрдорд┐рд│ рдкрд░рд┐рд╕реНрдерд┐рддреА рд╢рдХреНрдп рдЖрд╣реЗ рдЬреЗрд╡реНрд╣рд╛ рд╕рд░реНрд╡ рддрддреНрддреНрд╡рдЬреНрдЮ рдбрд╛рд╡рд╛ рдХрд╛рдЯрд╛ рдШреЗрддрд╛рдд, рддреЗрдереЗ рдХреЛрдгреАрд╣реА рдЙрдЬрд╡рд╛ рдирд╕рддреЛ, рддреНрдпрд╛рдВрдиреА рдбрд╛рд╡реАрдХрдбреЗ рдареЗрд╡рд▓реЗ, рдерд╛рдВрдмрд╛, рдкреБрдиреНрд╣рд╛ рдбрд╛рд╡реАрдХрдбреЗ рдШреНрдпрд╛, рдЗ. рд╣реА рдкрд░рд┐рд╕реНрдерд┐рддреА рджреЗрдЦреАрд▓ рдЙрдкрд╛рд╕рдорд╛рд░реАрдЪреА рдЖрд╣реЗ, рдЕрдзрд┐рдХрд╛рдзрд┐рдХ рдЧрддрд┐рд░реЛрдзрдХ рдЖрд╣реЗ. рдореА рддреНрдпрд╛рдЪреА рдкреБрдирд░рд╛рд╡реГрддреНрддреА рдХрд░рдгреНрдпрд╛рдд рдЕрдпрд╢рд╕реНрд╡реА рдЭрд╛рд▓реЛ. рдЦрд╛рд▓реА рдЕрд╢рд╛ рдкрд░рд┐рд╕реНрдерд┐рддреАрдЪреЗ рдЪрд┐рддреНрд░ рдЖрд╣реЗ рдЬрд┐рдереЗ рджреЛрди рд╡рд╛рдИрдЯ рддрддреНрд╡рдЬреНрдЮрд╛рдВрдиреА рджреЛрдиреНрд╣реА рдХрд╛рдЯреЗ рдШреЗрддрд▓реЗ рдЖрд╣реЗрдд рдЖрдгрд┐ рджреЛрди рдЪрд╛рдВрдЧрд▓реЗ рднреБрдХреЗрд▓реЗ рдЖрд╣реЗрдд.

рд╡реЗрд▓-рдлреЗрдб рдлрд┐рд▓реЙрд╕реЙрдлрд░ рдХрд┐рдВрд╡рд╛ рд╕реНрдкрд░реНрдзрд╛рддреНрдордХ .NET рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ

рдпреЗрдереЗ рдЖрдкрдг рдкрд╛рд╣реВ рд╢рдХрддрд╛ рдХреА рдзрд╛рдЧреЗ рдХрдзреАрдХрдзреА рдЬрд╛рдЧреЗ рд╣реЛрддрд╛рдд рдЖрдгрд┐ рд╕рдВрд╕рд╛рдзрди рдорд┐рд│рд╡рд┐рдгреНрдпрд╛рдЪрд╛ рдкреНрд░рдпрддреНрди рдХрд░рддрд╛рдд. рдЪрд╛рд░рдкреИрдХреА рджреЛрди рдХреЛрд░ рдХрд╛рд╣реАрд╣реА рдХрд░рдд рдирд╛рд╣реАрдд (рд╡рд░реАрд▓ рд╣рд┐рд░рд╡рд╛ рдЖрд▓реЗрдЦ).

рдПрдХрд╛ рддрддреНрд╡рд╡реЗрддреНрддреНрдпрд╛рдЪрд╛ рдореГрддреНрдпреВ

рдмрд░рдВ, рддрддреНрддреНрд╡рдЬреНрдЮрд╛рдВрдЪреНрдпрд╛ рд╡реИрднрд╡рд╢рд╛рд▓реА рд░рд╛рддреНрд░реАрдЪреНрдпрд╛ рдЬреЗрд╡рдгрд╛рдд рд╡реНрдпрддреНрдпрдп рдЖрдгрдгрд╛рд░реА рдЖрдгрдЦреА рдПрдХ рд╕рдорд╕реНрдпрд╛ рдореНрд╣рдгрдЬреЗ рддреНрдпрд╛рдВрдЪреНрдпрд╛рдкреИрдХреА рдПрдЦрд╛рджрд╛ рдЕрдЪрд╛рдирдХ рд╣рд╛рддрд╛рдд рдХрд╛рдЯреЗ рдШреЗрдКрди рдорд░рдг рдкрд╛рд╡рд▓рд╛ (рдЖрдгрд┐ рддреЗ рддреНрдпрд╛рд▓рд╛ рдЕрд╕реЗрдЪ рджрдлрди рдХрд░рддреАрд▓). рдордЧ рд╢реЗрдЬрд╛рд░реА рдЬреЗрд╡рдгрд╛рд╢рд┐рд╡рд╛рдп рд╕реЛрдбрд▓реЗ рдЬрд╛рддреАрд▓. рдЖрдкрдг рд╕реНрд╡рдд: рдпрд╛ рдХреЗрд╕рд╕рд╛рдареА рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЛрдб рдШреЗрдКрди рдпреЗрдК рд╢рдХрддрд╛, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рддреЗ рдмрд╛рд╣реЗрд░ рдлреЗрдХрд▓реЗ рдЖрд╣реЗ NullReferenceException рддрддреНрд╡рдЬреНрдЮрд╛рдиреА рдХрд╛рдЯреЗ рдШреЗрддрд▓реНрдпрд╛рдирдВрддрд░. рдЖрдгрд┐, рддрд╕реЗ, рдЕрдкрд╡рд╛рдж рд╣рд╛рддрд╛рд│рд▓рд╛ рдЬрд╛рдгрд╛рд░ рдирд╛рд╣реА рдЖрдгрд┐ рдХреЙрд▓рд┐рдВрдЧ рдХреЛрдб рдлрдХреНрдд рдкрдХрдбрдгрд╛рд░ рдирд╛рд╣реА (рдпрд╛рд╕рд╛рдареА AppDomain.CurrentDomain.UnhandledException рдЖрдгрд┐ рдЗ.). рдореНрд╣рдгреВрди, рдереНрд░реЗрдбреНрд╕рдордзреНрдпреЗ рд╕реНрд╡рддрдГ рдЖрдгрд┐ рд╕реБрдВрджрд░ рд╕рдорд╛рдкреНрддреАрд╕рд╣ рддреНрд░реБрдЯреА рд╣рд╛рддрд╛рд│рдгрд╛рд░реЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗрдд.

рд╡реЗрдЯрд░

рдареАрдХ рдЖрд╣реЗ, рд╣реА рдЧрддрд┐рд░реЛрдз, рдЙрдкрд╛рд╕рдорд╛рд░ рдЖрдгрд┐ рдореГрддреНрдпреВрдЪреА рд╕рдорд╕реНрдпрд╛ рдХрд╢реА рд╕реЛрдбрд╡рд╛рдпрдЪреА? рдЖрдореНрд╣реА рдлрдХреНрдд рдПрдХрд╛ рддрддреНрд╡рдЬреНрдЮрд╛рдиреА рдлреЙрд░реНрдХреНрд╕рдкрд░реНрдпрдВрдд рдкреЛрд╣реЛрдЪреВ рджреЗрдК, рдпрд╛ рдард┐рдХрд╛рдгрд╛рд╕рд╛рдареА рдереНрд░реЗрдбреНрд╕рдЪрд╛ рдкрд░рд╕реНрдкрд░ рдмрд╣рд┐рд╖реНрдХрд╛рд░ рдЬреЛрдбрд╛. рддреЗ рдХрд╕реЗ рдХрд░рд╛рдпрдЪреЗ? рд╕рдордЬрд╛ рдХреА рдПрдХ рд╡реЗрдЯрд░ рддрддреНрддреНрд╡рдЬреНрдЮрд╛рдВрдЪреНрдпрд╛ рд╢реЗрдЬрд╛рд░реА рдЙрднрд╛ рдЖрд╣реЗ, рдЬреЛ рдХреЛрдгрддреНрдпрд╛рд╣реА рдПрдХрд╛ рддрддреНрддреНрд╡рд╡реЗрддреНрддреНрдпрд╛рд▓рд╛ рдХрд╛рдЯреЗ рдШреЗрдгреНрдпрд╛рд╕ рдкрд░рд╡рд╛рдирдЧреА рджреЗрддреЛ. рд╣рд╛ рд╡реЗрдЯрд░ рдХрд╕рд╛ рдмрдирд╡рд╛рдпрдЪрд╛ рдЖрдгрд┐ рддрддреНрддреНрд╡рдЬреНрдЮ рддреНрдпрд╛рд▓рд╛ рдХрд╕реЗ рд╡рд┐рдЪрд╛рд░рддреАрд▓, рд╣реЗ рдкреНрд░рд╢реНрди рдордиреЛрд░рдВрдЬрдХ рдЖрд╣реЗрдд.

рд╕рд░реНрд╡рд╛рдд рд╕реЛрдкрд╛ рдорд╛рд░реНрдЧ рдореНрд╣рдгрдЬреЗ рдЬреЗрд╡реНрд╣рд╛ рддрддреНрд╡рдЬреНрдЮрд╛рдиреА рд╡реЗрдЯрд░рд▓рд╛ рдХрд╛рдЯреНрдпрд╛рдВрдордзреНрдпреЗ рдкреНрд░рд╡реЗрд╢ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рд╕рддрдд рд╡рд┐рдЪрд╛рд░рддреАрд▓. рддреНрдпрд╛. рдЖрддрд╛ рддрддреНрд╡рдЬреНрдЮрд╛рдиреА рдЬрд╡рд│рдЪреНрдпрд╛ рдХрд╛рдЯреНрдпрд╛рдЪреА рд╡рд╛рдЯ рдкрд╛рд╣рдгрд╛рд░ рдирд╛рд╣реАрдд, рддрд░ рдерд╛рдВрдмрд╛ рдХрд┐рдВрд╡рд╛ рд╡реЗрдЯрд░рд▓рд╛ рд╡рд┐рдЪрд╛рд░рд╛. рд╕реБрд░реБрд╡рд╛рддреАрд▓рд╛, рдЖрдореНрд╣реА рдпрд╛рд╕рд╛рдареА рдлрдХреНрдд рдпреБрдЬрд░ рд╕реНрдкреЗрд╕ рд╡рд╛рдкрд░рддреЛ, рддреНрдпрд╛рдордзреНрдпреЗ рдЖрдореНрд╣реА рдХрд░реНрдирд▓рдордзреВрди рдХреЛрдгрддреАрд╣реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЙрд▓ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдЗрдВрдЯрд░рдкреНрдЯреНрд╕ рд╡рд╛рдкрд░рдд рдирд╛рд╣реА (рддреНрдпрд╛рдмрджреНрджрд▓ рдЦрд╛рд▓реА).

рд╡рд╛рдкрд░рдХрд░реНрддрд╛ рдЬрд╛рдЧрд╛ рдордзреНрдпреЗ рдЙрдкрд╛рдп

рдпреЗрдереЗ рдЖрдкрдг рдПрдХ рдХрд╛рдЯрд╛ рдЖрдгрд┐ рджреЛрди рддрддреНрд╡рдЬреНрдЮрд╛рдиреА рд╡рд╛рдкрд░рдд рд╣реЛрддреЛ рддреЗрдЪ рдХрд░реВ, рдЖрдкрдг рдЪрдХреНрд░рд╛рдд рдлрд┐рд░реВ рдЖрдгрд┐ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реВ. рдкрд░рдВрддреБ рдЖрддрд╛ рддреЗ рд╕рд░реНрд╡ рддрддреНрддреНрд╡рдЬреНрдЮ рдЕрд╕рддреАрд▓ рдЖрдгрд┐ рдЬрд╕реЗ рддреЗ рд╣реЛрддреЗ, рдлрдХреНрдд рдПрдХ рдХрд╛рдЯрд╛, рдореНрд╣рдгрдЬреЗ. рдЕрд╕реЗ рдореНрд╣рдгрддрд╛ рдпреЗрдИрд▓ рдХреА рд╡реЗрдЯрд░рдХрдбреВрди рд╣рд╛ тАЬрд╕реЛрдиреЗрд░реА рдХрд╛рдЯрд╛тАЭ рдШреЗрдгрд╛рд░рд╛ рдХреЗрд╡рд│ рддрддреНрддреНрд╡рдЬреНрдЮрдЪ рдЦрд╛рдИрд▓. рдпрд╛рд╕рд╛рдареА рдЖрдкрдг SpinLock рд╡рд╛рдкрд░рддреЛ.

private static SpinLock spinLock = new SpinLock();  // ╨Э╨░╤И "╨╛╤Д╨╕╤Ж╨╕╨░╨╜╤В"
private void RunSpinLock(int i, CancellationToken token)
{
    while (true)
    {
        // ╨Т╨╖╨░╨╕╨╝╨╜╨░╤П ╨▒╨╗╨╛╨║╨╕╤А╨╛╨▓╨║╨░ ╤З╨╡╤А╨╡╨╖ busy waiting. ╨Т╤Л╨╖╤Л╨▓╨░╨╡╨╝ ╨┤╨╛ try, ╤З╤В╨╛╨▒╤Л
        // ╨▓╤Л╨▒╤А╨░╤Б╨╕╤В╤М ╨╕╤Б╨║╨╗╤О╤З╨╡╨╜╨╕╨╡ ╨▓ ╤Б╨╗╤Г╤З╨░╨╡ ╨╛╤И╨╕╨▒╨║╨╕ ╨▓ ╤Б╨░╨╝╨╛╨╝ SpinLock.
        bool hasLock = false;
        spinLock.Enter(ref hasLock);
        try
        {
            // ╨Ч╨┤╨╡╤Б╤М ╨╝╨╛╨╢╨╡╤В ╨▒╤Л╤В╤М ╤В╨╛╨╗╤М╨║╨╛ ╨╛╨┤╨╕╨╜ ╨┐╨╛╤В╨╛╨║ (mutual exclusion).
            forks[Left(i)] = i + 1;  // ╨С╨╡╤А╨╡╨╝ ╨▓╨╕╨╗╨║╤Г ╤Б╤А╨░╨╖╤Г, ╨▒╨╡╨╖ ╨╛╨╢╨╕╨┤╨░╨╜╨╕╤П.
            forks[Right(i)] = i + 1;
            eatenFood[i] = (eatenFood[i] + 1) % (int.MaxValue - 1);
            forks[Left(i)] = 0;
            forks[Right(i)] = 0;
        }
        finally
        {
            if(hasLock) spinLock.Exit();  // ╨Ш╨╖╨▒╨╡╨│╨░╨╡╨╝ ╨┐╤А╨╛╨▒╨╗╨╡╨╝╤Л ╤Б╨╛ ╤Б╨╝╨╡╤А╤В╤М╤О ╤Д╨╕╨╗╨╛╤Б╨╛╤Д╨░.
        }

        Think(i);

        if (token.IsCancellationRequested)
            break;
    }
}

SpinLock рд╣реЗ рдПрдХ рдмреНрд▓реЙрдХрд░ рдЖрд╣реЗ, рд╕рд╛рдзрд╛рд░рдгрдкрдгреЗ, рд╕рдорд╛рди рдЖрд╣реЗ while(true) { if (!lock) break; }, рдкрдг рддреНрдпрд╛рд╣реВрди рдЕрдзрд┐рдХ "рдЬрд╛рджреВ" рд╕рд╣ SpinWait (рдЬреЗ рддрд┐рдереЗ рд╡рд╛рдкрд░рд▓реЗ рдЬрд╛рддреЗ). рдЖрддрд╛ рд╡рд╛рдЯ рдкрд╛рд╣рдгрд╛рд▒реНрдпрд╛рдВрдЪреА рдЧрдгрдирд╛ рдХрд╢реА рдХрд░рд╛рдпрдЪреА, рддреНрдпрд╛рдВрдирд╛ рдереЛрдбреЗ рдЭреЛрдкрд╛рдпрдЪреЗ рдЖрдгрд┐ рдмрд░реЗрдЪ рдХрд╛рд╣реА рдХрд╕реЗ рдХрд░рд╛рдпрдЪреЗ рд╣реЗ рддреНрдпрд╛рд▓рд╛ рдорд╛рд╣реАрдд рдЖрд╣реЗ. рдЗ. рд╕рд░реНрд╡рд╕рд╛рдзрд╛рд░рдгрдкрдгреЗ, рдСрдкреНрдЯрд┐рдорд╛рдЗрдЭ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рд╕рд░реНрд╡рдХрд╛рд╣реА рд╢рдХреНрдп рдХрд░рддреЗ. рдкрд░рдВрддреБ рдЖрдкрдг рд╣реЗ рд▓рдХреНрд╖рд╛рдд рдареЗрд╡рд▓реЗ рдкрд╛рд╣рд┐рдЬреЗ рдХреА рд╣реЗ рдЕрджреНрдпрд╛рдкрд╣реА рддреЗрдЪ рд╕рдХреНрд░рд┐рдп рдЪрдХреНрд░ рдЖрд╣реЗ рдЬреЗ рдкреНрд░реЛрд╕реЗрд╕рд░ рд╕рдВрд╕рд╛рдзрдиреЗ рдЦрд╛рдКрди рдЯрд╛рдХрддреЗ рдЖрдгрд┐ рдкреНрд░рд╡рд╛рд╣ рдЪрд╛рд▓реВ рдареЗрд╡рддреЗ, рдЬреНрдпрд╛рдореБрд│реЗ рдПрдЦрд╛рджреНрдпрд╛ рддрддреНрддреНрд╡рд╡реЗрддреНрддреНрдпрд╛рд▓рд╛ рдЗрддрд░рд╛рдВрдкреЗрдХреНрд╖рд╛ рдЕрдзрд┐рдХ рдкреНрд░рд╛рдзрд╛рдиреНрдп рджрд┐рд▓реНрдпрд╛рд╕ рдЙрдкрд╛рд╕рдорд╛рд░ рд╣реЛрдК рд╢рдХрддреЗ, рдкрд░рдВрддреБ рддреНрдпрд╛рд▓рд╛ рд╕реЛрдиреЗрд░реА рдХрд╛рдЯрд╛ рдирд╕реЗрд▓ (рдкреНрд░рд╛рдзрд╛рдиреНрдп рдЙрд▓рдЯрд╛ рд╕рдорд╕реНрдпрд╛) . рдореНрд╣рдгреВрди, рдЖрдореНрд╣реА рддреЗ рдХреЛрдгрддреНрдпрд╛рд╣реА рддреГрддреАрдп-рдкрдХреНрд╖ рдХреЙрд▓, рдиреЗрд╕реНрдЯреЗрдб рд▓реЙрдХ рдЖрдгрд┐ рдЗрддрд░ рдЖрд╢реНрдЪрд░реНрдпрд╛рдВрд╢рд┐рд╡рд╛рдп рдХреЗрд╡рд│ рд╕рд╛рдорд╛рдпрд┐рдХ рдореЗрдорд░реАрдордзреАрд▓ рдЕрдЧрджреА рд▓рд╣рд╛рди рдмрджрд▓рд╛рдВрд╕рд╛рдареА рд╡рд╛рдкрд░рддреЛ.

рд╡реЗрд▓-рдлреЗрдб рдлрд┐рд▓реЙрд╕реЙрдлрд░ рдХрд┐рдВрд╡рд╛ рд╕реНрдкрд░реНрдзрд╛рддреНрдордХ .NET рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ

рд╕рд╛рдареА рд░реЗрдЦрд╛рдВрдХрди SpinLock. рд╕реЛрдиреЗрд░реА рдХрд╛рдЯреНрдпрд╛рд╕рд╛рдареА рдкреНрд░рд╡рд╛рд╣ рд╕рддрдд "рд▓рдврдд" рдЕрд╕рддрд╛рдд. рддреЗрдереЗ рдЕрдкрдпрд╢ рдЖрд╣реЗрдд - рдЖрдХреГрддреАрдордзреНрдпреЗ, рдирд┐рд╡рдбрд▓реЗрд▓реЗ рдХреНрд╖реЗрддреНрд░. рдХреЛрд░ рдкреВрд░реНрдгрдкрдгреЗ рд╡рд╛рдкрд░рд▓реЗрд▓реЗ рдирд╛рд╣реАрдд: рдпрд╛ рдЪрд╛рд░ рдереНрд░реЗрдбреНрд╕рджреНрд╡рд╛рд░реЗ рдлрдХреНрдд 2/3.

рдпреЗрдереЗ рджреБрд╕рд░рд╛ рдЙрдкрд╛рдп рдлрдХреНрдд рд╡рд╛рдкрд░рдгреЗ рдЕрд╕реЗрд▓ Interlocked.CompareExchange рдЙрдкрд░реЛрдХреНрдд рдХреЛрдбрдордзреНрдпреЗ рджрд░реНрд╢рд╡рд┐рд▓реНрдпрд╛рдкреНрд░рдорд╛рдгреЗ рд╕рдорд╛рди рд╕рдХреНрд░рд┐рдп рдкреНрд░рддреАрдХреНрд╖рд╛рд╕рд╣ (рдЙрдкрд╛рд╢реА рддрддреНрддреНрд╡рдЬреНрдЮрд╛рдиреА), рдкрд░рдВрддреБ рд╣реЗ, рдЖрдзреАрдЪ рдореНрд╣рдЯрд▓реНрдпрд╛рдкреНрд░рдорд╛рдгреЗ, рд╕реИрджреНрдзрд╛рдВрддрд┐рдХрджреГрд╖реНрдЯреНрдпрд╛ рдЕрд╡рд░реЛрдзрд┐рдд рд╣реЛрдК рд╢рдХрддреЗ.

рд╡рд░ Interlocked рд╣реЗ рд▓рдХреНрд╖рд╛рдд рдШреЗрддрд▓реЗ рдкрд╛рд╣рд┐рдЬреЗ рдХреА рдирд╛рд╣реА рдлрдХреНрдд рдЖрд╣реЗ CompareExchange, рдкрд░рдВрддреБ рдЕрдгреВ рд╡рд╛рдЪрди рдЖрдгрд┐ рд▓реЗрдЦрдирд╛рд╕рд╛рдареА рдЗрддрд░ рдкрджреНрдзрддреА рджреЗрдЦреАрд▓. рдЖрдгрд┐ рдмрджрд▓рд╛рдЪреНрдпрд╛ рдкреБрдирд░рд╛рд╡реГрддреНрддреАрджреНрд╡рд╛рд░реЗ, рджреБрд╕рд░реНтАНрдпрд╛ рдереНрд░реЗрдбрдордзреНрдпреЗ рдмрджрд▓ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рд╡реЗрд│ рдЕрд╕рд▓реНрдпрд╛рд╕ (рд╡рд╛рдЪрд╛ 1, рд╡рд╛рдЪрд╛ 2, рд▓рд┐рд╣рд╛ 2, рд▓рд┐рд╣рд╛ 1 рдЦрд░рд╛рдм рдЖрд╣реЗ), рддреЗ рдПрдХрд╛ рдореВрд▓реНрдпрд╛рддреАрд▓ рдЬрдЯрд┐рд▓ рдмрджрд▓рд╛рдВрд╕рд╛рдареА рд╡рд╛рдкрд░рд▓реЗ рдЬрд╛рдК рд╢рдХрддреЗ (рдЗрдВрдЯрд░рд▓реЙрдХ рдХреЗрд▓реЗрд▓реЗ рдХрд╛рд╣реАрд╣реА рдкреЕрдЯрд░реНрди) .

рдХрд░реНрдирд▓ рдореЛрдб рд╕реЛрд▓реНрдпреВрд╢рдиреНрд╕

рд▓реВрдкрдордзреНрдпреЗ рд╕рдВрд╕рд╛рдзрдирд╛рдВрдЪрд╛ рдЕрдкрд╡реНрдпрдп рдЯрд╛рд│рдгреНрдпрд╛рд╕рд╛рдареА, рдЖрдкрдг рдзрд╛рдЧрд╛ рдХрд╕рд╛ рдмреНрд▓реЙрдХ рдХрд░реВ рд╢рдХрддреЛ рддреЗ рдкрд╛рд╣реВ. рджреБрд╕рд▒реНрдпрд╛ рд╢рдмреНрджрд╛рдВрдд, рдЖрдкрд▓реЗ рдЙрджрд╛рд╣рд░рдг рдкреБрдвреЗ рдЪрд╛рд▓реВ рдареЗрд╡рдд, рд╡реЗрдЯрд░ рддрддреНрддреНрд╡рд╡реЗрддреНрддреНрдпрд╛рд▓рд╛ рдХрд╕реЗ рдЭреЛрдкрд╡рддреЛ рдЖрдгрд┐ рдЖрд╡рд╢реНрдпрдХ рдЕрд╕реЗрд▓ рддреЗрд╡реНрд╣рд╛рдЪ рддреНрдпрд╛рд▓рд╛ рдХрд╕реЗ рдЙрдард╡рддреЛ рддреЗ рдкрд╛рд╣реВ. рдкреНрд░рдердо, рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдордЪреНрдпрд╛ рдХрд░реНрдирд▓ рдореЛрдбрджреНрд╡рд╛рд░реЗ рд╣реЗ рдХрд╕реЗ рдХрд░рд╛рдпрдЪреЗ рддреЗ рдкрд╛рд╣реВ. рддреЗрдереАрд▓ рд╕рд░реНрд╡ рд╕рдВрд░рдЪрдирд╛ рд╡рд╛рдкрд░рдХрд░реНрддреНрдпрд╛рдЪреНрдпрд╛ рдЬрд╛рдЧреЗрдд рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рд╕рдВрд░рдЪрдиреЗрдкреЗрдХреНрд╖рд╛ рдмрд░реНтАНрдпрд╛рдЪрджрд╛ рд╣рд│реВ рдЕрд╕рддрд╛рдд. рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдЕрдиреЗрдХ рд╡реЗрд│рд╛ рд╣рд│реВ AutoResetEvent рдХрджрд╛рдЪрд┐рдд 53 рдкрдЯ рд╣рд│реВ SpinLock [рд░рд┐рд╢реНрдЯрд░]. рдкрд░рдВрддреБ рддреНрдпрд╛рдВрдЪреНрдпрд╛ рдорджрддреАрдиреЗ, рдЖрдкрдг рд╕рдВрдкреВрд░реНрдг рд╕рд┐рд╕реНрдЯрдордордзреНрдпреЗ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕рдордХреНрд░рдорд┐рдд рдХрд░реВ рд╢рдХрддрд╛, рд╡реНрдпрд╡рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдВрд╡рд╛ рдирд╛рд╣реА.

рдЕрд░реНрдзрд╢рддрдХрд╛рдкреВрд░реНрд╡реА рдбрд┐рдЬрдХреНрд╕реНрдЯреНрд░рд╛рдиреЗ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдХреЗрд▓реЗрд▓рд╛ рд╕реЗрдорд╛рдлреЛрд░ рдпреЗрдереЗ рдореВрд│ рд░рдЪрдирд╛ рдЖрд╣реЗ. рд╕реЗрдорд╛рдлреЛрд░ рдореНрд╣рдгрдЬреЗ, рд╕реЛрдкреНрдпрд╛ рднрд╛рд╖реЗрдд, рд╕рд┐рд╕реНрдЯрдорджреНрд╡рд╛рд░реЗ рд╡реНрдпрд╡рд╕реНрдерд╛рдкрд┐рдд рдХреЗрд▓реЗрд▓рд╛ рдПрдХ рд╕рдХрд╛рд░рд╛рддреНрдордХ рдкреВрд░реНрдгрд╛рдВрдХ рдЖрдгрд┐ рддреНрдпрд╛рд╡рд░ рджреЛрди рдСрдкрд░реЗрд╢рдиреНрд╕, рд╡рд╛рдв рдЖрдгрд┐ рдШрдЯ. рдЬрд░ рддреЗ рдХрдореА рд╣реЛрдгреНрдпрд╛рд╕ рдЕрдпрд╢рд╕реНрд╡реА рдЭрд╛рд▓реЗ, рд╢реВрдиреНрдп, рддрд░ рдХреЙрд▓рд┐рдВрдЧ рдереНрд░реЗрдб рдЕрд╡рд░реЛрдзрд┐рдд рдХреЗрд▓рд╛ рдЬрд╛рдИрд▓. рдЬреЗрд╡реНрд╣рд╛ рд╕рдВрдЦреНрдпрд╛ рдЗрддрд░ рдХрд╛рд╣реА рд╕рдХреНрд░рд┐рдп рдереНрд░реЗрдб/рдкреНрд░рдХреНрд░рд┐рдпреЗрджреНрд╡рд╛рд░реЗ рд╡рд╛рдврд╡рд┐рд▓реА рдЬрд╛рддреЗ, рддреЗрд╡реНрд╣рд╛ рдереНрд░реЗрдб рд╡рдЧрд│рд▓реЗ рдЬрд╛рддрд╛рдд рдЖрдгрд┐ рдкрд╛рд╕ рдХреЗрд▓реЗрд▓реНрдпрд╛ рд╕рдВрдЦреНрдпреЗрдиреЗ рд╕реЗрдорд╛рдлреЛрд░ рдкреБрдиреНрд╣рд╛ рдХрдореА рдХреЗрд▓рд╛ рдЬрд╛рддреЛ. рд╕реЗрдорд╛рдлреЛрд░ рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рдЯреНрд░реЗрдиреНрд╕рдЪреА рдХрд▓реНрдкрдирд╛ рдХрд░рддрд╛ рдпреЗрддреЗ. .NET рд╕рдорд╛рди рдХрд╛рд░реНрдпрдХреНрд╖рдорддреЗрд╕рд╣ рдЕрдиреЗрдХ рд░рдЪрдирд╛ рдСрдлрд░ рдХрд░рддреЗ: AutoResetEvent, ManualResetEvent, Mutex рдЖрдгрд┐ рдореА Semaphore. рдЖрдореНрд╣реА рд╡рд╛рдкрд░реВ AutoResetEvent, рдпрд╛ рдмрд╛рдВрдзрдХрд╛рдорд╛рдВрдкреИрдХреА рд╣реА рд╕рд░реНрд╡рд╛рдд рд╕реЛрдкреА рдЖрд╣реЗ: рдлрдХреНрдд рджреЛрди рдореВрд▓реНрдпреЗ 0 рдЖрдгрд┐ 1 (рдЦреЛрдЯреЗ, рдЦрд░реЗ). рддрд┐рдЪреА рдкрджреНрдзрдд WaitOne() рдЬрд░ рдореВрд▓реНрдп 0 рдЕрд╕реЗрд▓ рддрд░ рдХреЙрд▓рд┐рдВрдЧ рдереНрд░реЗрдб рдмреНрд▓реЙрдХ рдХрд░рддреЗ рдЖрдгрд┐ рдЬрд░ 1 рдЕрд╕реЗрд▓ рддрд░ рддреЗ 0 рд╡рд░ рдХрдореА рдХрд░рддреЗ рдЖрдгрд┐ рддреЗ рд╡рдЧрд│рддреЗ. рдПрдХ рдкрджреНрдзрдд Set() 1 рдкрд░реНрдпрдВрдд рд╡рд╛рдврд╡рддреЛ рдЖрдгрд┐ рдПрдХрд╛ рд╡реЗрдЯрд░рд▓рд╛ рдЬрд╛рдК рджреЗрддреЛ, рдЬреЛ рдкреБрдиреНрд╣рд╛ 0 рдкрд░реНрдпрдВрдд рдХрдореА рдХрд░рддреЛ. рд╕рдмрд╡реЗ рдЯрд░реНрдирд╕реНрдЯрд╛рдЗрд▓рд╕рд╛рд░рдЦреЗ рдХрд╛рд░реНрдп рдХрд░рддреЗ.

рдЪрд▓рд╛ рдЙрдкрд╛рдп рдХреНрд▓рд┐рд╖реНрдЯ рдХрд░реВ рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ рддрддреНрд╡рдЬреНрдЮрд╛рдирд╛рд╕рд╛рдареА рд▓реЙрдХ рд╡рд╛рдкрд░реВ, рдЖрдгрд┐ рдПрдХрд╛рдЪ рд╡реЗрд│реА рд╕рд░реНрд╡рд╛рдВрд╕рд╛рдареА рдирд╛рд╣реА. рддреНрдпрд╛. рдЖрддрд╛ рдПрдХрд╛рдЪ рд╡реЗрд│реА рдЕрдиреЗрдХ рддрддреНрддреНрд╡рдЬреНрдЮ рдЕрд╕реВ рд╢рдХрддрд╛рдд, рдПрдХ рдирд╛рд╣реА. рдкрд░рдВрддреБ рдЖрдореНрд╣реА рдпреЛрдЧреНрдпрд░рд┐рддреНрдпрд╛, рд╢рд░реНрдпрддреА (рд╢рд░реНрдпрддреАрдЪреА рдкрд░рд┐рд╕реНрдерд┐рддреА) рдЯрд╛рд│рдгреНрдпрд╛рд╕рд╛рдареА, рдЦрд╛рддреНрд░реАрдиреЗ рдмреЗрдЯреНрд╕ рдШреЗрдгреНрдпрд╛рд╕рд╛рдареА рдЯреЗрдмрд▓рд╡рд░ рдкреНрд░рд╡реЗрд╢ рдкреБрдиреНрд╣рд╛ рдЕрд╡рд░реЛрдзрд┐рдд рдХрд░рддреЛ.

// ╨Ф╨╗╤П ╨▒╨╗╨╛╨║╨╕╤А╨╛╨▓╨░╨╜╨╕╤П ╨╛╤В╨┤╨╡╨╗╤М╨╜╨╛╨│╨╛ ╤Д╨╕╨╗╨╛╤Б╨╛╤Д╨░.
// ╨Ш╨╜╨╕╤Ж╨╕╨░╨╗╨╕╨╖╨╕╤А╤Г╨╡╤В╤Б╤П: new AutoResetEvent(true) ╨┤╨╗╤П ╨║╨░╨╢╨┤╨╛╨│╨╛.
private AutoResetEvent[] philosopherEvents;

// ╨Ф╨╗╤П ╨┤╨╛╤Б╤В╤Г╨┐╨░ ╨║ ╨▓╨╕╨╗╨║╨░╨╝ / ╨┤╨╛╤Б╤В╤Г╨┐ ╨║ ╤Б╤В╨╛╨╗╤Г.
private AutoResetEvent tableEvent = new AutoResetEvent(true);

// ╨а╨╛╨╢╨┤╨╡╨╜╨╕╨╡ ╤Д╨╕╨╗╨╛╤Б╨╛╤Д╨░.
public void Run(int i, CancellationToken token)
{
    while (true)
    {
        TakeForks(i); // ╨Ц╨┤╨╡╤В ╨▓╨╕╨╗╨║╨╕.
        // ╨Ю╨▒╨╡╨┤. ╨Ь╨╛╨╢╨╡╤В ╨▒╤Л╤В╤М ╨╕ ╨┤╨╛╨╗╤М╤И╨╡.
        eatenFood[i] = (eatenFood[i] + 1) % (int.MaxValue - 1);
        PutForks(i); // ╨Ю╤В╨┤╨░╤В╤М ╨▓╨╕╨╗╨║╨╕ ╨╕ ╤А╨░╨╖╨▒╨╗╨╛╨║╨╕╤А╨╛╨▓╨░╤В╤М ╤Б╨╛╤Б╨╡╨┤╨╡╨╣.
        Think(i);
        if (token.IsCancellationRequested) break;
    }
}

// ╨Ю╨╢╨╕╨┤╨░╤В╤М ╨▓╨╕╨╗╨║╨╕ ╨▓ ╨▒╨╗╨╛╨║╨╕╤А╨╛╨▓╨║╨╡.
void TakeForks(int i)
{
    bool hasForks = false;
    while (!hasForks) // ╨Я╨╛╨┐╤А╨╛╨▒╨╛╨▓╨░╤В╤М ╨╡╤Й╨╡ ╤А╨░╨╖ (╨▒╨╗╨╛╨║╨╕╤А╨╛╨▓╨║╨░ ╨╜╨╡ ╨╖╨┤╨╡╤Б╤М).
    {
        // ╨Ш╤Б╨║╨╗╤О╤З╨░╤О╤Й╨╕╨╣ ╨┤╨╛╤Б╤В╤Г╨┐ ╨║ ╤Б╤В╨╛╨╗╤Г, ╨▒╨╡╨╖ ╨│╨╛╨╜╨╛╨║ ╨╖╨░ ╨▓╨╕╨╗╨║╨░╨╝╨╕.
        tableEvent.WaitOne();
        if (forks[Left(i)] == 0 && forks[Right(i)] == 0)
            forks[Left(i)] = forks[Right(i)] = i + 1;
        hasForks = forks[Left(i)] == i + 1 && forks[Right(i)] == i + 1;
        if (hasForks)
            // ╨в╨╡╨┐╨╡╤А╤М ╤Д╨╕╨╗╨╛╤Б╨╛╤Д ╨┐╨╛╨╡╤Б╤В, ╨▓╤Л╨╣╨┤╨╡╤В ╨╕╨╖ ╤Ж╨╕╨║╨╗╨░. ╨Х╤Б╨╗╨╕ Set 
            // ╨▓╤Л╨╖╨▓╨░╨╜ ╨┤╨▓╨░╨╢╨┤╤Л, ╤В╨╛ ╨╖╨╜╨░╤З╨╡╨╜╨╕╨╡ true.
            philosopherEvents[i].Set();
        // ╨а╨░╨╖╨▒╨╗╨╛╨║╨╕╤А╨╛╨▓╨░╤В╤М ╨╛╨┤╨╜╨╛╨│╨╛ ╨╛╨╢╨╕╨┤╨░╤О╤Й╨╡╨│╨╛. ╨Я╨╛╤Б╨╗╨╡ ╨╜╨╡╨│╨╛ ╨╖╨╜╨░╤З╨╡╨╜╨╕╨╡ tableEvent ╨▓ false.
        tableEvent.Set(); 
        // ╨Х╤Б╨╗╨╕ ╨╕╨╝╨╡╨╡╤В true, ╨╜╨╡ ╨▒╨╗╨╛╨║╨╕╤А╤Г╨╡╤В╤Б╤П, ╨░ ╨╡╤Б╨╗╨╕ false, ╤В╨╛ ╨▒╤Г╨┤╨╡╤В ╨╢╨┤╨░╤В╤М Set ╨╛╤В ╤Б╨╛╤Б╨╡╨┤╨░.
        philosopherEvents[i].WaitOne();
    }
}

// ╨Ю╤В╨┤╨░╤В╤М ╨▓╨╕╨╗╨║╨╕ ╨╕ ╤А╨░╨╖╨▒╨╗╨╛╨║╨╕╤А╨╛╨▓╨░╤В╤М ╤Б╨╛╤Б╨╡╨┤╨╡╨╣.
void PutForks(int i)
{
    tableEvent.WaitOne(); // ╨С╨╡╨╖ ╨│╨╛╨╜╨╛╨║ ╨╖╨░ ╨▓╨╕╨╗╨║╨░╨╝╨╕.
    forks[Left(i)] = 0;
    // ╨Я╤А╨╛╨▒╤Г╨┤╨╕╤В╤М ╨╗╨╡╨▓╨╛╨│╨╛, ╨░ ╨┐╨╛╤В╨╛╨╝ ╨╕ ╨┐╤А╨░╨▓╨╛╨│╨╛ ╤Б╨╛╤Б╨╡╨┤╨░, ╨╗╨╕╨▒╨╛ AutoResetEvent ╨▓ true.
    philosopherEvents[LeftPhilosopher(i)].Set();
    forks[Right(i)] = 0;
    philosopherEvents[RightPhilosopher(i)].Set();
    tableEvent.Set();
}

рдпреЗрдереЗ рдХрд╛рдп рдШрдбрдд рдЖрд╣реЗ рд╣реЗ рд╕рдордЬреВрди рдШреЗрдгреНрдпрд╛рд╕рд╛рдареА, рдЬреЗрд╡реНрд╣рд╛ рддрддреНрд╡рдЬреНрдЮрд╛рдиреА рдХрд╛рдЯреЗ рдШреЗрдгреНрдпрд╛рд╕ рдЕрдпрд╢рд╕реНрд╡реА рдЭрд╛рд▓рд╛ рддреЗрд╡реНрд╣рд╛ рдкреНрд░рдХрд░рдгрд╛рдЪрд╛ рд╡рд┐рдЪрд╛рд░ рдХрд░рд╛, рдирдВрддрд░ рддреНрдпрд╛рдЪреНрдпрд╛ рдХреГрддреА рдЦрд╛рд▓реАрд▓рдкреНрд░рдорд╛рдгреЗ рдЕрд╕рддреАрд▓. рддреЛ рдЯреЗрдмрд▓рд╡рд░ рдкреНрд░рд╡реЗрд╢рд╛рдЪреА рд╡рд╛рдЯ рдкрд╛рд╣рдд рдЖрд╣реЗ. рддреЗ рдорд┐рд│рд╛рд▓реНрдпрд╛рд╡рд░ рддреЛ рдХрд╛рдЯреЗ рдШреЗрдгреНрдпрд╛рдЪрд╛ рдкреНрд░рдпрддреНрди рдХрд░рддреЛ. рдХрд╛рдо рдХреЗрд▓реЗ рдирд╛рд╣реА. рд╣реЗ рдЯреЗрдмрд▓рдордзреНрдпреЗ рдкреНрд░рд╡реЗрд╢ рджреЗрддреЗ (рдореНрдпреБрдЪреНрдпреБрдЕрд▓ рдЕрдкрд╡рд░реНрдЬрди). рдЖрдгрд┐ рддреНрдпрд╛рдЪреЗ "рдЯрд░реНрдирд╕реНрдЯрд╛рдЗрд▓" рдкрд╛рд╕ рдХрд░рддреЗ (AutoResetEvent) (рддреЗ рд╕реБрд░реБрд╡рд╛рддреАрд▓рд╛ рдЙрдШрдбреЗ рдЖрд╣реЗрдд). рддреЛ рдкреБрдиреНрд╣рд╛ рдЪрдХреНрд░рд╛рдд рдпреЗрддреЛ, рдХрд╛рд░рдг рддреНрдпрд╛рд▓рд╛ рдХрд╛рдЯреЗ рдирд╛рд╣реАрдд. рддреЛ рддреНрдпрд╛рдВрдирд╛ рдШреЗрдгреНрдпрд╛рдЪрд╛ рдкреНрд░рдпрддреНрди рдХрд░рддреЛ рдЖрдгрд┐ рддреНрдпрд╛рдЪреНрдпрд╛ "рдЯрд░реНрдирд╕реНрдЯрд╛рдЗрд▓" рд╡рд░ рдерд╛рдВрдмрддреЛ. рдЙрдЬрд╡реАрдХрдбреЗ рдХрд┐рдВрд╡рд╛ рдбрд╛рд╡реАрдХрдбреЗ рдЖрдгрдЦреА рдХрд╛рд╣реА рднрд╛рдЧреНрдпрд╡рд╛рди рд╢реЗрдЬрд╛рд░реА, рдЦрд╛рдгреЗ рд╕рдВрдкрд╡реВрди, рдЖрдордЪреНрдпрд╛ рддрддреНрд╡рдЬреНрдЮрд╛рдиреА "рддреНрдпрд╛рдЪрд╛ рдЯрд░реНрдирд╕реНрдЯрд╛рдИрд▓ рдЙрдШрдбрдд рдЖрд╣реЗ." рдЖрдордЪреЗ рддрддреНрд╡рдЬреНрдЮрд╛рдиреА рддреЗ рджреБрд╕рд▒реНрдпрд╛рдВрджрд╛ рдкрд╛рд╕ рдХрд░рддрд╛рдд (рдЖрдгрд┐ рддреЗ рддреНрдпрд╛рдЪреНрдпрд╛ рдорд╛рдЧреЗ рдмрдВрдж рд╣реЛрддреЗ). рддреЛ рддрд┐рд╕рд▒реНрдпрд╛рдВрджрд╛ рдХрд╛рдЯреЗ рдШреЗрдгреНрдпрд╛рдЪрд╛ рдкреНрд░рдпрддреНрди рдХрд░рддреЛ. рд╢реБрднреЗрдЪреНрдЫрд╛. рдЖрдгрд┐ рддреЛ рддреНрдпрд╛рдЪреНрдпрд╛ рдЯрд░реНрдирд╕реНрдЯрд╛рдИрд▓рд▓рд╛ рдЬреЗрд╡рд╛рдпрд▓рд╛ рдЬрд╛рддреЛ.

рдЬреЗрд╡реНрд╣рд╛ рдЕрд╢рд╛ рдХреЛрдбрдордзреНрдпреЗ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рддреНрд░реБрдЯреА рдЕрд╕рддрд╛рдд (рддреНрдпрд╛ рдиреЗрд╣рдореА рдЕрд╕реНрддрд┐рддреНрд╡рд╛рдд рдЕрд╕рддрд╛рдд), рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рд╢реЗрдЬрд╛рд░реА рдЪреБрдХреАрдЪреНрдпрд╛ рдкрджреНрдзрддреАрдиреЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХреЗрд▓рд╛ рдЬрд╛рддреЛ рдХрд┐рдВрд╡рд╛ рд╕рдорд╛рди рдСрдмреНрдЬреЗрдХреНрдЯ рддрдпрд╛рд░ рдХреЗрд▓рд╛ рдЬрд╛рддреЛ. AutoResetEvent рд╕рдЧрд│реНрдпрд╛рдВрд╕рд╛рдареА (Enumerable.Repeat), рдордЧ рддрддреНрд╡рдЬреНрдЮрд╛рдиреА рд╡рд┐рдХрд╕рдХрд╛рдВрдЪреА рд╡рд╛рдЯ рдкрд╛рд╣рдд рдЕрд╕рддреАрд▓, рдХрд╛рд░рдг рдЕрд╢рд╛ рдХреЛрдбрдордзреАрд▓ рддреНрд░реБрдЯреА рд╢реЛрдзрдгреЗ рдЦреВрдк рдХрдареАрдг рдХрд╛рдо рдЖрд╣реЗ. рдпрд╛ рд╕реЛрд▓реНрдпреВрд╢рдирдордзреНрдпреЗ рдЖрдгрдЦреА рдПрдХ рд╕рдорд╕реНрдпрд╛ рдЕрд╢реА рдЖрд╣реЗ рдХреА рдХрд╛рд╣реА рддрддреНрд╡рдЬреНрдЮрд╛рдиреА рдЙрдкрд╛рд╢реА рд░рд╛рд╣рдгрд╛рд░ рдирд╛рд╣реАрдд рдпрд╛рдЪреА рд╣рдореА рджреЗрдд тАЛтАЛтАЛтАЛрдирд╛рд╣реА.

рд╕рдВрдХрд░рд┐рдд рдЙрдкрд╛рдп

рдЖрдореНрд╣реА рд╡реЗрд│реЗрд╕рд╛рдареА рджреЛрди рджреГрд╖реНрдЯрд┐рдХреЛрди рдкрд╛рд╣рд┐рд▓реЗ рдЖрд╣реЗрдд, рдЬреЗрд╡реНрд╣рд╛ рдЖрдореНрд╣реА рд╡рд╛рдкрд░рдХрд░реНрддрд╛ рдореЛрдб рдЖрдгрд┐ рд▓реВрдкрдордзреНрдпреЗ рд░рд╛рд╣рддреЛ рдЖрдгрд┐ рдЬреЗрд╡реНрд╣рд╛ рдЖрдореНрд╣реА рдХрд░реНрдирд▓рджреНрд╡рд╛рд░реЗ рдереНрд░реЗрдб рдмреНрд▓реЙрдХ рдХрд░рддреЛ. рдкрд╣рд┐рд▓реА рдкрджреНрдзрдд рд▓рд╣рд╛рди рд▓реЙрдХрд╕рд╛рдареА рдЪрд╛рдВрдЧрд▓реА рдЖрд╣реЗ, рджреБрд╕рд░реА рд▓рд╛рдВрдм рд▓реЛрдХрд╛рдВрд╕рд╛рдареА. рд▓реВрдкрдордзреНрдпреЗ рд╡реНрд╣реЗрд░рд┐рдПрдмрд▓ рдмрджрд▓рдгреНрдпрд╛рд╕рд╛рдареА рдкреНрд░рдердо рдереЛрдбрдХреНрдпрд╛рдд рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдгреЗ рдЖрдгрд┐ рдирдВрддрд░ рдкреНрд░рддреАрдХреНрд╖рд╛ рд▓рд╛рдВрдм рдЕрд╕рддрд╛рдирд╛ рдереНрд░реЗрдб рдЕрд╡рд░реЛрдзрд┐рдд рдХрд░рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЕрд╕рддреЗ. рд╣рд╛ рджреГрд╖реНрдЯрд┐рдХреЛрди рддрдерд╛рдХрдерд┐рдд рдордзреНрдпреЗ рдЕрдВрдорд▓рд╛рдд рдЖрдгрд▓рд╛ рдЬрд╛рддреЛ. рд╕рдВрдХрд░рд┐рдд рд╕рдВрд░рдЪрдирд╛. рдпреЗрдереЗ рдХрд░реНрдирд▓ рдореЛрдбрд╕рд╛рдареА рд╕рдорд╛рди рд░рдЪрдирд╛ рдЖрд╣реЗрдд, рдкрд░рдВрддреБ рдЖрддрд╛ рд╡рд╛рдкрд░рдХрд░реНрддрд╛ рдореЛрдб рд▓реВрдкрд╕рд╣: SemaphorSlim, ManualResetEventSlim рдЗ. рдпреЗрдереЗ рд╕рд░реНрд╡рд╛рдд рд▓реЛрдХрдкреНрд░рд┐рдп рдбрд┐рдЭрд╛рдЗрди рдЖрд╣реЗ Monitor, рдХрд╛рд░рдг C# рдордзреНрдпреЗ рдПрдХ рд╕реБрдкреНрд░рд╕рд┐рджреНрдз рдЖрд╣реЗ lock рдорд╛рдВрдбрдгреА. Monitor 1 (рдореНрдпреБрдЯреЗрдХреНрд╕) рдЪреЗ рдХрдорд╛рд▓ рдореВрд▓реНрдп рдЕрд╕рд▓реЗрд▓реЗ рд╣реЗ рд╕рдорд╛рди рд╕реЗрдорд╛рдлреЛрд░ рдЖрд╣реЗ, рдкрд░рдВрддреБ рд▓реВрдкрдордзреНрдпреЗ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рд╕рдорд░реНрдердирд╛рд╕рд╣, рдкреБрдирд░рд╛рд╡реГрддреНрддреА, рдХрдВрдбрд┐рд╢рди рд╡реНрд╣реЗрд░рд┐рдПрдмрд▓ рдкреЕрдЯрд░реНрди (рдЦрд╛рд▓реА рддреНрдпрд╛рдмрджреНрджрд▓ рдЕрдзрд┐рдХ), рдЗ. рдпрд╛рд╕рд╣ рдПрдХ рдЙрдкрд╛рдп рдкрд╛рд╣реВ рдпрд╛.

// ╨б╨┐╤А╤П╤З╨╡╨╝ ╨╛╨▒╤К╨╡╨║╤В ╨┤╨╗╤П ╨Ь╨╛╨╜╨╕╤В╨╛╤А╨░ ╨╛╤В ╨▓╤Б╨╡╤Е, ╤З╤В╨╛╨▒╤Л ╨▒╨╡╨╖ ╨┤╨╡╨┤╨╗╨╛╨║╨╛╨▓.
private readonly object _lock = new object();
// ╨Т╤А╨╡╨╝╤П ╨╛╨╢╨╕╨┤╨░╨╜╨╕╤П ╨┐╨╛╤В╨╛╨║╨░.
private DateTime?[] _waitTimes = new DateTime?[philosophersAmount];

public void Run(int i, CancellationToken token)
{
    while (true)
    {
        TakeForks(i);
        eatenFood[i] = (eatenFood[i] + 1) % (int.MaxValue - 1);
        PutForks(i);
        Think(i);
        if (token.IsCancellationRequested) break;
    }
}

// ╨Э╨░╤И╨╡ ╤Б╨╗╨╛╨╢╨╜╨╛╨╡ ╤Г╤Б╨╗╨╛╨▓╨╕╨╡ ╨┤╨╗╤П Condition Variable ╨┐╨░╤В╤В╨╡╤А╨╜╨░.
bool CanIEat(int i)
{
    // ╨Х╤Б╨╗╨╕ ╨╡╤Б╤В╤М ╨▓╨╕╨╗╨║╨╕:
    if (forks[Left(i)] != 0 && forks[Right(i)] != 0)
        return false;
    var now = DateTime.Now;
    // ╨Ь╨╛╨╢╨╡╤В, ╨╡╤Б╨╗╨╕ ╤Б╨╛╤Б╨╡╨┤╨╕ ╨╜╨╡ ╨▒╨╛╨╗╨╡╨╡ ╨│╨╛╨╗╨╛╨┤╨╜╤Л╨╡, ╤З╨╡╨╝ ╤В╨╡╨║╤Г╤Й╨╕╨╣.
    foreach(var p in new int[] {LeftPhilosopher(i), RightPhilosopher(i)})
        if (_waitTimes[p] != null && now - _waitTimes[p] > now - _waitTimes[i])
            return false;
    return true;
}

void TakeForks(int i)
{
    // ╨Ч╨░╨╣╤В╨╕ ╨▓ ╨Ь╨╛╨╜╨╕╤В╨╛╤А. ╨в╨╛ ╨╢╨╡ ╤Б╨░╨╝╨╛╨╡: lock(_lock) {..}.
    // ╨Т╤Л╨╖╤Л╨▓╨░╨╡╨╝ ╨▓╨╜╨╡ try, ╤З╤В╨╛╨▒╤Л ╨▓╨╛╨╖╨╝╨╛╨╢╨╜╨╛╨╡ ╨╕╤Б╨║╨╗╤О╤З╨╡╨╜╨╕╨╡ ╨▓╤Л╨▒╤А╨░╤Б╤Л╨▓╨░╨╗╨╛╤Б╤М ╨▓╤Л╤И╨╡.
    bool lockTaken = false;
    Monitor.Enter(_lock, ref lockTaken);
    try
    {
        _waitTimes[i] = DateTime.Now;
        // Condition Variable ╨┐╨░╤В╤В╨╡╤А╨╜. ╨Ю╤Б╨▓╨╛╨▒╨╛╨╢╨┤╨░╨╡╨╝ ╨╗╨╛╨║, ╨╡╤Б╨╗╨╕ ╨╜╨╡ ╨▓╤Л╨┐╨╛╨╗╨╜╨╡╨╜╨╜╨╛ 
        // ╤Б╨╗╨╛╨╢╨╜╨╛╨╡ ╤Г╤Б╨╗╨╛╨▓╨╕╨╡. ╨Ш ╨╢╨┤╨╡╨╝ ╨┐╨╛╨║╨░ ╨║╤В╨╛-╨╜╨╕╨▒╤Г╨┤╤М ╤Б╨┤╨╡╨╗╨░╨╡╤В Pulse / PulseAll.
        while (!CanIEat(i))
            Monitor.Wait(_lock); 
        forks[Left(i)] = i + 1;
        forks[Right(i)] = i + 1;
        _waitTimes[i] = null;
    }
    finally
    {
        if (lockTaken) Monitor.Exit(_lock);
    }
}

void PutForks(int i)
{
    // ╨в╨╛ ╨╢╨╡ ╤Б╨░╨╝╨╛╨╡: lock (_lock) {..}.
    bool lockTaken = false;
    Monitor.Enter(_lock, ref lockTaken);
    try
    {
        forks[Left(i)] = 0;
        forks[Right(i)] = 0;
        // ╨Ю╤Б╨▓╨╛╨▒╨╛╨┤╨╕╤В╤М ╨▓╤Б╨╡ ╨┐╨╛╤В╨╛╨║╨╕ ╨▓ ╨╛╤З╨╡╤А╨╡╨┤╨╕ ╨Я╨Ю╨б╨Ы╨Х ╨▓╤Л╨╖╨╛╨▓╨░ Monitor.Exit.
        Monitor.PulseAll(_lock); 
    }
    finally
    {
        if (lockTaken) Monitor.Exit(_lock);
    }
}

рдпреЗрдереЗ рдЖрдореНрд╣реА рдлреЙрд░реНрдХреНрд╕рдордзреНрдпреЗ рдкреНрд░рд╡реЗрд╢ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рд╕рдВрдкреВрд░реНрдг рдЯреЗрдмрд▓ рдкреБрдиреНрд╣рд╛ рдЕрд╡рд░реЛрдзрд┐рдд рдХрд░рдд рдЖрд╣реЛрдд, рдкрд░рдВрддреБ рдЖрддрд╛ рдЖрдореНрд╣реА рдПрдХрд╛рдЪ рд╡реЗрд│реА рд╕рд░реНрд╡ рдереНрд░реЗрдбреНрд╕ рдЕрдирдмреНрд▓реЙрдХ рдХрд░рдд рдЖрд╣реЛрдд, рдЖрдгрд┐ рдХреЛрдгреАрддрд░реА рдЦрд╛рд▓реНрд▓реНрдпрд╛рдирдВрддрд░ рд╢реЗрдЬрд╛рд░реА рдирд╛рд╣реА. рддреНрдпрд╛. рдкреНрд░рдердо, рдХреЛрдгреАрддрд░реА рдЦрд╛рддреЛ рдЖрдгрд┐ рд╢реЗрдЬрд╛рд▒реНрдпрд╛рдВрдирд╛ рдЕрдбрд╡рддреЛ, рдЖрдгрд┐ рдЬреЗрд╡реНрд╣рд╛ рд╣реЗ рдХреЛрдгреАрддрд░реА рд╕рдВрдкрддреЗ, рдкрд░рдВрддреБ рд▓рдЧреЗрдЪ рдкреБрдиреНрд╣рд╛ рдЦрд╛рдпрдЪреЗ рдЕрд╕рддреЗ рддреЗрд╡реНрд╣рд╛ рддреЛ рдмреНрд▓реЙрдХрд┐рдВрдЧрдордзреНрдпреЗ рдЬрд╛рддреЛ рдЖрдгрд┐ рд╢реЗрдЬрд╛рд▒реНрдпрд╛рдВрдирд╛ рдЙрдард╡рддреЛ, рдХрд╛рд░рдг. рддреНрдпрд╛рдЪреА рдкреНрд░рддреАрдХреНрд╖рд╛ рд╡реЗрд│ рдХрдореА рдЖрд╣реЗ.

рдЕрд╢рд╛ рдкреНрд░рдХрд╛рд░реЗ рдЖрдкрдг рдЧрддрд┐рд░реЛрдзрдХ рдЖрдгрд┐ рдХрд╛рд╣реА рддрддреНрд╡рдЬреНрдЮрд╛рдиреА рдЙрдкрд╛рд╕рдорд╛рд░ рдЯрд╛рд│рддреЛ. рдЖрдореНрд╣реА рдереЛрдбреНрдпрд╛ рдкреНрд░рддреАрдХреНрд╖рд╛рд╕рд╛рдареА рд▓реВрдк рд╡рд╛рдкрд░рддреЛ рдЖрдгрд┐ рд▓рд╛рдВрдмрд╕рд╛рдареА рдзрд╛рдЧрд╛ рдЕрд╡рд░реЛрдзрд┐рдд рдХрд░рддреЛ. рдПрдХрд╛рдЪ рд╡реЗрд│реА рдкреНрд░рддреНрдпреЗрдХрд╛рд▓рд╛ рдЕрдирдмреНрд▓реЙрдХ рдХрд░рдгреЗ рд╣реЗ рдлрдХреНрдд рд╢реЗрдЬрд╛рд░реАрдЪ рдЕрдирдмреНрд▓реЙрдХ рдХреЗрд▓реЗ рдЕрд╕рд▓реНтАНрдпрд╛рдкреЗрдХреНрд╖рд╛ рдзреАрдореЗ рдЖрд╣реЗ, рдЬрд╕реЗ рдХреА рд╕реЛрд▓реНрдпреВрд╢рдирдордзреНрдпреЗ рдЖрд╣реЗ AutoResetEvent, рдкрд░рдВрддреБ рдлрд░рдХ рдореЛрдард╛ рдирд╕рд╛рд╡рд╛, рдХрд╛рд░рдг рдереНрд░реЗрдбреНрд╕ рдкреНрд░рдердо рд╡рд╛рдкрд░рдХрд░реНрддрд╛ рдореЛрдбрдордзреНрдпреЗ рд░рд╛рд╣рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ.

╨г lock рд╡рд╛рдХреНрдпрд░рдЪрдирд╛рдордзреНрдпреЗ рдУрдВрдЧрд│ рдЖрд╢реНрдЪрд░реНрдп рдЖрд╣реЗ. рд╡рд╛рдкрд░рдгреНрдпрд╛рдЪреА рд╢рд┐рдлрд╛рд░рд╕ рдХрд░рддрд╛рдд Monitor рдереЗрдЯ [рд░рд┐рдХреНрдЯрд░] [рдПрд░рд┐рдХ рд▓рд┐рдкреНрдкрд░реНрдЯ]. рддреНрдпрд╛рдкреИрдХреА рдПрдХ рдЖрд╣реЗ lock рдиреЗрд╣рдореА рдмрд╛рд╣реЗрд░ Monitor, рдЕрдкрд╡рд╛рдж рдЕрд╕рд▓рд╛ рддрд░реАрд╣реА, рдЕрд╢рд╛ рдкрд░рд┐рд╕реНрдерд┐рддреАрдд рджреБрд╕рд░рд╛ рдереНрд░реЗрдб рд╕рд╛рдорд╛рдпрд┐рдХ рдореЗрдорд░реА рд╕реНрдерд┐рддреА рдмрджрд▓реВ рд╢рдХрддреЛ. рдЕрд╢рд╛ рдкрд░рд┐рд╕реНрдерд┐рддреАрдд, рдбреЗрдбрд▓реЙрдХрдордзреНрдпреЗ рдЬрд╛рдгреЗ рдХрд┐рдВрд╡рд╛ рдХрд╕рд╛ рддрд░реА рд╕реБрд░рдХреНрд╖рд┐рддрдкрдгреЗ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╕рдорд╛рдкреНрдд рдХрд░рдгреЗ рдЪрд╛рдВрдЧрд▓реЗ рдЕрд╕рддреЗ. рдЖрдгрдЦреА рдПрдХ рдЖрд╢реНрдЪрд░реНрдп рдореНрд╣рдгрдЬреЗ рдореЙрдирд┐рдЯрд░ рд╕рд┐рдВрдХреНрд░реЛрдирд╛рдЗрдЭреЗрд╢рди рдмреНрд▓реЙрдХреНрд╕ рд╡рд╛рдкрд░рддреЛ (SyncBlock), рдЬреЗ рд╕рд░реНрд╡ рд╡рд╕реНрддреВрдВрдордзреНрдпреЗ рдЙрдкрд╕реНрдерд┐рдд рдЕрд╕рддрд╛рдд. рдореНрд╣рдгреВрди, рдЕрдпреЛрдЧреНрдп рдСрдмреНрдЬреЗрдХреНрдЯ рдирд┐рд╡рдбрд▓реНрдпрд╛рд╕, рдЖрдкрдг рд╕рд╣рдЬрдкрдгреЗ рдПрдХ рдбреЗрдбрд▓реЙрдХ рдорд┐рд│рд╡реВ рд╢рдХрддрд╛ (рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдЖрдкрдг рдЗрдВрдЯрд░реНрди рд╕реНрдЯреНрд░рд┐рдВрдЧрд╡рд░ рд▓реЙрдХ рдХреЗрд▓реНрдпрд╛рд╕). рдпрд╛рд╕рд╛рдареА рдЖрдкрдг рдиреЗрд╣рдореА рд▓рдкрд▓реЗрд▓реА рд╡рд╕реНрддреВ рд╡рд╛рдкрд░рддреЛ.

рдХрдВрдбрд┐рд╢рди рд╡реНрд╣реЗрд░рд┐рдПрдмрд▓ рдкреЕрдЯрд░реНрди рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рд╣реА рдЬрдЯрд┐рд▓ рд╕реНрдерд┐рддреАрдЪреА рдЕрдкреЗрдХреНрд╖рд╛ рдЕрдзрд┐рдХ рд╕рдВрдХреНрд╖рд┐рдкреНрддрдкрдгреЗ рдЕрдВрдорд▓рд╛рдд рдЖрдгрдгреНрдпрд╛рдЪреА рдкрд░рд╡рд╛рдирдЧреА рджреЗрддреЛ. .NET рдордзреНрдпреЗ, рддреЗ рдЕрдкреВрд░реНрдг рдЖрд╣реЗ, рдорд╛рдЭреНрдпрд╛ рдорддреЗ, рдХрд╛рд░рдг рд╕рд┐рджреНрдзрд╛рдВрддрд╛рдиреБрд╕рд╛рд░, рдЕрдиреЗрдХ рд╡реНрд╣реЗрд░рд┐рдПрдмрд▓реНрд╕рд╡рд░ (рдкреЙрд╕рд┐рдХреНрд╕ рдереНрд░реЗрдбреНрд╕рдкреНрд░рдорд╛рдгреЗ) рдЕрдиреЗрдХ рд░рд╛рдВрдЧрд╛ рдЕрд╕рд╛рд╡реНрдпрд╛рдд, рдПрдХрд╛ рд▓реЛрдХрд╛рд╡рд░ рдирд╛рд╣реА. рдордЧ рддреЗ рд╕рд░реНрд╡ рддрддреНрддреНрд╡рдЬреНрдЮрд╛рдВрд╕рд╛рдареА рдмрдирд╡реВ рд╢рдХрддрд╛рдд. рдкрд░рдВрддреБ рдпрд╛ рдлреЙрд░реНрдордордзреНрдпреЗ рджреЗрдЦреАрд▓, рддреЗ рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рдХреЛрдб рдХрдореА рдХрд░рдгреНрдпрд╛рд╕ рдЕрдиреБрдорддреА рджреЗрддреЗ.

рдЕрдиреЗрдХ рддрддреНрд╡рдЬреНрдЮ рдХрд┐рдВрд╡рд╛ async / await

рдареАрдХ рдЖрд╣реЗ, рдЖрддрд╛ рдЖрдореНрд╣реА рдереНрд░реЗрдб рдкреНрд░рднрд╛рд╡реАрдкрдгреЗ рдмреНрд▓реЙрдХ рдХрд░реВ рд╢рдХрддреЛ. рдкрдг рдЖрдкрд▓реНрдпрд╛рдХрдбреЗ рдЕрдиреЗрдХ рддрддреНрддреНрд╡рдЬреНрдЮ рдЕрд╕рддреАрд▓ рддрд░? 100? 10000? рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдЖрдореНрд╣рд╛рд▓рд╛ рд╡реЗрдм рд╕рд░реНрд╡реНрд╣рд░рд▓рд╛ 100000 рд╡рд┐рдирдВрддреНрдпрд╛ рдорд┐рд│рд╛рд▓реНрдпрд╛. рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдирдВрддреАрд╕рд╛рдареА рдереНрд░реЗрдб рддрдпрд╛рд░ рдХрд░рдгреЗ рдУрд╡реНрд╣рд░рд╣реЗрдб рдЕрд╕реЗрд▓, рдХрд╛рд░рдг рдЗрддрдХреЗ рдзрд╛рдЧреЗ рд╕рдорд╛рдВрддрд░ рдЪрд╛рд▓рдгрд╛рд░ рдирд╛рд╣реАрдд. рд▓реЙрдЬрд┐рдХрд▓ рдХреЛрд░ рдЖрд╣реЗрдд рддрд┐рддрдХреЗрдЪ рдЪрд╛рд▓рддреАрд▓ (рдорд╛рдЭреНрдпрд╛рдХрдбреЗ 4 рдЖрд╣реЗрдд). рдЖрдгрд┐ рдмрд╛рдХреАрдЪреЗ рд╕рдЧрд│реЗ рдлрдХреНрдд рд╕рдВрд╕рд╛рдзрдиреЗ рдХрд╛рдвреВрди рдШреЗрддреАрд▓. рдпрд╛ рд╕рдорд╕реНрдпреЗрдЪрд╛ рдПрдХ рдЙрдкрд╛рдп рдореНрд╣рдгрдЬреЗ async/await pattern. рддреНрдпрд╛рдЪреА рдХрд▓реНрдкрдирд╛ рдЕрд╢реА рдЖрд╣реЗ рдХреА рдлрдВрдХреНрд╢рди рдереНрд░реЗрдб рдзрд░реВрди рдареЗрд╡рдд рдирд╛рд╣реА рдЬрд░ рддреНрдпрд╛рд▓рд╛ рдХрд╛рд╣реАрддрд░реА рд╕реБрд░реВ рдареЗрд╡рдгреНрдпрд╛рд╕рд╛рдареА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рд╛рд╡реА рд▓рд╛рдЧреЗрд▓. рдЖрдгрд┐ рдЬреЗрд╡реНрд╣рд╛ рддреЗ рдХрд╛рд╣реА рдХрд░рддреЗ, рддреЗрд╡реНрд╣рд╛ рддреЗ рддреНрдпрд╛рдЪреА рдЕрдВрдорд▓рдмрдЬрд╛рд╡рдгреА рдкреБрдиреНрд╣рд╛ рд╕реБрд░реВ рдХрд░рддреЗ (рдкрд░рдВрддреБ рддреНрдпрд╛рдЪ рдзрд╛рдЧреНрдпрд╛рд╡рд░ рдЖрд╡рд╢реНрдпрдХ рдирд╛рд╣реА!). рдЖрдордЪреНрдпрд╛ рдмрд╛рдмрддреАрдд, рдЖрдореНрд╣реА рдХрд╛рдЯреНрдпрд╛рдЪреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реВ.

SemaphoreSlim рдпрд╛рд╕рд╛рдареА рдЖрд╣реЗ WaitAsync() рдкрджреНрдзрдд рд╣рд╛ рдирдореБрдирд╛ рд╡рд╛рдкрд░реВрди рдЕрдВрдорд▓рдмрдЬрд╛рд╡рдгреА рдпреЗрдереЗ рдЖрд╣реЗ.

// ╨Ч╨░╨┐╤Г╤Б╨║ ╤В╨░╨║╨╛╨╣ ╨╢╨╡, ╨║╨░╨║ ╤А╨░╨╜╤М╤И╨╡. ╨У╨┤╨╡-╨╜╨╕╨▒╤Г╨┤╤М ╨▓ ╨┐╤А╨╛╨│╤А╨░╨╝╨╝╨╡:
Task.Run(() => Run(i, cancelTokenSource.Token));

// ╨Ч╨░╨┐╤Г╤Б╨║ ╤Д╨╕╨╗╨╛╤Б╨╛╤Д╨░.
// ╨Ъ╨╗╤О╤З╨╡╨▓╨╛╨╡ ╤Б╨╗╨╛╨▓╨╛ async -- ╨║╨╛╨╝╨┐╨╕╨╗╤П╤В╨╛╤А ╤В╤А╨░╨╜╤Б╨╗╨╕╤А╤Г╨╡╤В ╤Н╤В╨╛╤В ╨╝╨╡╤В╨╛╤В ╨▓ ╨░╤Б╨╕╨╜╤Е╤А╨╛╨╜╨╜╤Л╨╣.
public async Task Run(int i, CancellationToken token)
{
    while (true)
    {
        // await -- ╨▒╤Г╨┤╨╡╨╝ ╨╛╨╢╨╕╨┤╨░╤В╤М ╨║╨░╨║╨╛╨│╨╛-╤В╨╛ ╤Б╨╛╨▒╤Л╤В╨╕╤П.
        await TakeForks(i);
        // ╨Я╨╛╤Б╨╗╨╡ await, ╨┐╤А╨╛╨┤╨╛╨╗╨╢╨╡╨╜╨╕╨╡ ╨▓╨╛╨╖╨╝╨╛╨╢╨╜╨╛ ╨▓ ╨┤╤А╤Г╨│╨╛╨╝ ╨┐╨╛╤В╨╛╨║╨╡.
        eatenFood[i] = (eatenFood[i] + 1) % (int.MaxValue - 1);
        // ╨Ь╨╛╨╢╨╡╤В ╨▒╤Л╤В╤М ╨╜╨╡╤Б╨║╨╛╨╗╤М╨║╨╛ ╤Б╨╛╨▒╤Л╤В╨╕╨╣ ╨┤╨╗╤П ╨╛╨╢╨╕╨┤╨░╨╜╨╕╤П.
        await PutForks(i);

        Think(i);

        if (token.IsCancellationRequested) break;
    }
}

async Task TakeForks(int i)
{
    bool hasForks = false;
    while (!hasForks)
    {
        // ╨Т╨╖╨░╨╕╨╝╨╛╨╕╤Б╨║╨╗╤О╤З╨░╤О╤Й╨╕╨╣ ╨┤╨╛╤Б╤В╤Г╨┐ ╨║ ╤Б╤В╨╛╨╗╤Г:
        await _tableSemaphore.WaitAsync();
        if (forks[Left(i)] == 0 && forks[Right(i)] == 0)
        {
            forks[Left(i)] = i+1;
            forks[Right(i)] = i+1;
            hasForks = true;
        }
        _tableSemaphore.Release();
        // ╨С╤Г╨┤╨╡╨╝ ╨╛╨╢╨╕╨┤╨░╤В╤М, ╤З╤В╨╛╨▒╤Л ╤Б╨╛╤Б╨╡╨┤ ╨┐╨╛╨╗╨╛╨╢╨╕╨╗ ╨▓╨╕╨╗╨║╨╕:
        if (!hasForks)
            await _philosopherSemaphores[i].WaitAsync();
    }
}

// ╨Ц╨┤╨╡╨╝ ╨┤╨╛╤Б╤В╤Г╨┐╨░ ╨║ ╤Б╤В╨╛╨╗╤Г ╨╕ ╨║╨╗╨░╨┤╨╡╨╝ ╨▓╨╕╨╗╨║╨╕.
async Task PutForks(int i)
{
    await _tableSemaphore.WaitAsync();
    forks[Left(i)] = 0;
    // "╨Я╤А╨╛╨▒╤Г╨┤╨╕╤В╤М" ╤Б╨╛╤Б╨╡╨┤╨╡╨╣, ╨╡╤Б╨╗╨╕ ╨╛╨╜╨╕ "╤Б╨┐╨░╨╗╨╕".
    _philosopherSemaphores[LeftPhilosopher(i)].Release();
    forks[Right(i)] = 0;
    _philosopherSemaphores[RightPhilosopher(i)].Release();
    _tableSemaphore.Release();
}

рд╕рд╣ рдкрджреНрдзрдд async / await рдПрдХрд╛ рдЕрд╡рдШрдб рд╕реНрдЯреЗрдЯ рдорд╢реАрдирдордзреНрдпреЗ рднрд╛рд╖рд╛рдВрддрд░рд┐рдд рдХреЗрд▓реЗ рдЬрд╛рддреЗ рдЬреЗ рддреНрд╡рд░рд┐рдд рддреНрдпрд╛рдЪреЗ рдЕрдВрддрд░реНрдЧрдд рдкрд░рдд рдХрд░рддреЗ Task. рддреНрдпрд╛рджреНрд╡рд╛рд░реЗ, рддреБрдореНрд╣реА рдкрджреНрдзрдд рдкреВрд░реНрдг рд╣реЛрдгреНрдпрд╛рдЪреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реВ рд╢рдХрддрд╛, рддреА рд░рджреНрдж рдХрд░реВ рд╢рдХрддрд╛ рдЖрдгрд┐ рдЗрддрд░ рд╕рд░реНрд╡ рдХрд╛рд╣реА рдЬреЗ рддреБрдореНрд╣реА рдЯрд╛рд╕реНрдХрд╕рд╣ рдХрд░реВ рд╢рдХрддрд╛. рдкрджреНрдзрддреАрдЪреНрдпрд╛ рдЖрдд, рд░рд╛рдЬреНрдп рдорд╢реАрди рдЕрдВрдорд▓рдмрдЬрд╛рд╡рдгреАрд╡рд░ рдирд┐рдпрдВрддреНрд░рдг рдареЗрд╡рддреЗ. рддрд│ рдУрд│ рдЕрд╢реА рдЖрд╣реЗ рдХреА рдЬрд░ рд╡рд┐рд▓рдВрдм рдирд╕реЗрд▓ рддрд░ рдЕрдВрдорд▓рдмрдЬрд╛рд╡рдгреА рд╕рдордХрд╛рд▓рд┐рдХ рдЖрд╣реЗ рдЖрдгрд┐ рдЬрд░ рдЕрд╕реЗрд▓ рддрд░ рдзрд╛рдЧрд╛ рд╕реЛрдбрд▓рд╛ рдЬрд╛рдИрд▓. рд╣реЗ рдЕрдзрд┐рдХ рдЪрд╛рдВрдЧрд▓реНрдпрд╛ рдкреНрд░рдХрд╛рд░реЗ рд╕рдордЬреВрди рдШреЗрдгреНрдпрд╛рд╕рд╛рдареА, рд╣реЗ рд░рд╛рдЬреНрдп рдорд╢реАрди рдкрд╛рд╣рдгреЗ рдЪрд╛рдВрдЧрд▓реЗ рдЖрд╣реЗ. рдпрд╛рддреВрди рддреБрдореНрд╣реА рд╕рд╛рдЦрд│реА рддрдпрд╛рд░ рдХрд░реВ рд╢рдХрддрд╛ async / await рдкрджреНрдзрддреА

рдЪрд▓рд╛ рдЪрд╛рдЪрдгреА рдХрд░реВрдпрд╛. 100 рд▓реЙрдЬрд┐рдХрд▓ рдХреЛрд░, 4 рд╕реЗрдХрдВрдж рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рдорд╢реАрдирд╡рд░ 8 рддрддреНрд╡рдЬреНрдЮрд╛рдиреАрдВрдЪреЗ рдХрд╛рд░реНрдп. рдореЙрдирд┐рдЯрд░рд╕рд╣ рдорд╛рдЧреАрд▓ рд╕реЛрд▓реНрдпреВрд╢рдирдиреЗ рдлрдХреНрдд рдкрд╣рд┐рд▓реЗ 4 рдереНрд░реЗрдб рдЪрд╛рд▓рд╡рд▓реЗ рдЖрдгрд┐ рдмрд╛рдХреАрдЪреЗ рдЕрдЬрд┐рдмрд╛рдд рдЪрд╛рд▓рд▓реЗ рдирд╛рд╣реАрдд. рдпрд╛ 4 рдзрд╛рдЧреНрдпрд╛рдВрдкреИрдХреА рдкреНрд░рддреНрдпреЗрдХ 2ms рд╕рд╛рдареА рдирд┐рд╖реНрдХреНрд░рд┐рдп рд╣реЛрддрд╛. рдЖрдгрд┐ async/await рд╕реЛрд▓реНрдпреВрд╢рди рдкреНрд░рддреНрдпреЗрдХреА 100 рд╕реЗрдХрдВрджрд╛рдВрдЪреНрдпрд╛ рд╕рд░рд╛рд╕рд░реА рдкреНрд░рддреАрдХреНрд╖рд╛рд╕рд╣ рд╕рд░реНрд╡ 6.8 рдзрд╛рд╡рд▓реЗ. рдЕрд░реНрдерд╛рдд, рд░рд┐рдЕрд▓ рд╕рд┐рд╕реНрдЯреАрдордордзреНрдпреЗ, 6 рд╕реЗрдХрдВрджрд╛рдВрд╕рд╛рдареА рдирд┐рд╖реНрдХреНрд░рд┐рдпрддрд╛ рдЕрд╕реНрд╡реАрдХрд╛рд░реНрдп рдЖрд╣реЗ рдЖрдгрд┐ рдЕрд╢рд╛ рдЕрдиреЗрдХ рд╡рд┐рдирдВрддреНрдпрд╛рдВрд╡рд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рди рдХрд░рдгреЗ рдЪрд╛рдВрдЧрд▓реЗ рдЖрд╣реЗ. рдореЙрдирд┐рдЯрд░рд╕рд╣ рд╕реЛрд▓реНрдпреВрд╢рди рдЕрдЬрд┐рдмрд╛рдд рд╕реНрдХреЗрд▓реЗрдмрд▓ рдирд╛рд╣реА.

рдирд┐рд╖реНрдХрд░реНрд╖

рддреБрдореНрд╣реА рдпрд╛ рдЫреЛрдЯреНрдпрд╛ рдЙрджрд╛рд╣рд░рдгрд╛рдВрд╡рд░реВрди рдмрдШреВ рд╢рдХрддрд╛, .NET рдЕрдиреЗрдХ рд╕рд┐рдВрдХреНрд░реЛрдирд╛рдпрдЭреЗрд╢рди рдХрдиреНрд╕реНрдЯреНрд░рдХреНрдЯрд▓рд╛ рд╕рдкреЛрд░реНрдЯ рдХрд░рддреЗ. рддрдерд╛рдкрд┐, рддреЗ рдХрд╕реЗ рд╡рд╛рдкрд░рд╛рд╡реЗ рд╣реЗ рдиреЗрд╣рдореАрдЪ рд╕реНрдкрд╖реНрдЯ рдирд╕рддреЗ. рдорд▓рд╛ рдЖрд╢рд╛ рдЖрд╣реЗ рдХреА рд╣рд╛ рд▓реЗрдЦ рдЙрдкрдпреБрдХреНрдд рд╣реЛрддрд╛. рдЖрддреНрддрд╛рд╕рд╛рдареА, рд╣рд╛ рд╢реЗрд╡рдЯ рдЖрд╣реЗ, рдкрд░рдВрддреБ рдЕрдЬреВрдирд╣реА рдмрд░реНрдпрд╛рдЪ рдордиреЛрд░рдВрдЬрдХ рдЧреЛрд╖реНрдЯреА рд╢рд┐рд▓реНрд▓рдХ рдЖрд╣реЗрдд, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдереНрд░реЗрдб-рд╕реЗрдл рдХрд▓реЗрдХреНрд╢рди, TPL рдбреЗрдЯрд╛рдлреНрд▓реЛ, рд░рд┐рдНрдХреНрдЯрд┐рд╡реНрд╣ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ, рд╕реЙрдлреНрдЯрд╡реЗрдЕрд░ рдЯреНрд░рд╛рдиреНрдЭреЕрдХреНрд╢рди рдореЙрдбреЗрд▓ рдЗ.

рд╕реНрддреНрд░реЛрдд

рд╕реНрддреНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЬреЛрдбрд╛