рд╕рдорд╛рдирд╛рдВрддрд░ рдзрд╛рдЧрд╛ рдкрд░реАрдХреНрд╖рдг

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

рдФрд░ рдЖрдкрдХреЛ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИ?

рд╕рдорд╛рдирд╛рдВрддрд░ рд╕рд┐рд╕реНрдЯрдо рдмрдирд╛рдирд╛ рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рдХрд╛рдо рдирд╣реАрдВ рд╣реИред рд╕рдорд╛рдирддрд╛ рдФрд░ рд╕рдордХрд╛рд▓рд┐рдХрддрд╛ рдХреЗ рдмреАрдЪ рд╕рдВрддреБрд▓рди рдмрдирд╛рдП рд░рдЦрдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрджрд┐ рдЖрдк рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рд╕реНрдерд┐рд░рддрд╛ рдЦреЛ рджреЗрдВрдЧреЗред рдпрджрд┐ рдЖрдк рдкреБрди: рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдПрдХ рд╕реБрд╕рдВрдЧрдд рдкреНрд░рдгрд╛рд▓реА рдорд┐рд▓рддреА рд╣реИред

рд░реАрдлреИрдХреНрдЯрд░рд┐рдВрдЧ рдЖрдо рддреМрд░ рдкрд░ рдПрдХ рдорд╛рдЗрдирдлреАрд▓реНрдб рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЪрд▓рдирд╛ рд╣реИред

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

рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЖрдЦрд┐рд░рдХрд╛рд░ рдзрд╛рдЧреЗ рдХреЗ рдирд┐рд▓рдВрдмрди рдФрд░ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рд╣реЛ рдЧрдпрд╛ред рдЬреИрд╕рд╛ рдХрд┐ рдкрд╣рд▓реЗ рд╣реА рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдРрд╕рд╛ рдЧреИрд░-рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рддрдВрддреНрд░ рдореМрдЬреВрдж рд╣реИред рдпреЗ рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯ рд╣реИрдВред рд╣рдо рдПрдХ рдирдИ рд╢рдмреНрджрд╛рд╡рд▓реА рдХрд╛ рдЖрд╡рд┐рд╖реНрдХрд╛рд░ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ - рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯ, рдлрд┐рд░ рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯред

public class Breakpoint { [Conditional("DEBUG")] public static void Define(string name){тАж} } public class BreakCtrl : IDisposable { public string Name { get; private set; } public BreakCtrl(string name) {тАж} public BreakCtrl From(params Thread[] threads) {тАж} public void Dispose(){тАж} public void Run(Thread thread){тАж} public void Wait(Thread thread){тАж} public bool IsCapture(Thread thread){тАж} public Thread AnyCapture(){тАж} } 


рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯ рдХреЗ рдЧреБрдг:
  1. рд╡реЗ рдХреЗрд╡рд▓ рдбрд┐рдмрдЧ рдореЛрдб рдореЗрдВ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ (рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдореИрдХреНрд░реЛ DEBUG рдХреЗ рд╕рд╛рде)ред рд╣рдореЗрдВ рдпрд╣ рдирд╣реАрдВ рд╕реЛрдЪрдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдЕрддрд┐рд░рд┐рдХреНрдд рдХреЛрдб рдЕрдВрддрд┐рдо рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкрд░ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░реЗрдЧрд╛ред
  2. рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯ рдХреЗрд╡рд▓ рддрднреА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдЬрдм рдЗрд╕рдХрд╛ рдирд┐рдпрдВрддреНрд░рдХ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реЛред рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯ рдХреЛ рд╕рд┐рд╕реНрдЯрдо рдХрд╛ рдиреЗрддреГрддреНрд╡ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП (рдФрд░ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдЬрдЯрд┐рд▓ рдХрд░рдирд╛)ред
  3. рдирд┐рдпрдВрддреНрд░рдХ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯ рдХрд┐рд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╣реИ - рдХреНрдпрд╛ рдпрд╣ рдзрд╛рд░рд╛ рдХреЛ рдкрдХрдбрд╝рддрд╛ рд╣реИред
  4. рдирд┐рдпрдВрддреНрд░рдХ рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯ рдХреЛ рд╕реНрдЯреНрд░реАрдо рдЬрд╛рд░реА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╛рдзреНрдп рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИред
  5. рдФрд░ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдзрд╛рдЧреЗ рдХреЗ рд▓рд┐рдП рд╡реИрдХрд▓реНрдкрд┐рдХ рдмрд╛рдзреНрдпрдХрд╛рд░реАред рд╣рдо рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░рд╡рд╛рд╣ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рд╣рдо рд╣рд░ рдХрд┐рд╕реА рдХреЛ рдПрдХ рдмрд╛рд░ рдЪрд╛рд╣рддреЗ рд╣реИрдВред


 [TestMethod] public void StopStartThreadsTest_exemple1() { var log = new List<string>(); ThreadStart act1 = () => { Breakpoint.Define("empty"); Breakpoint.Define("start1"); log.Add("after start1"); Breakpoint.Define("step act1"); log.Add("after step act1"); Breakpoint.Define("finish1"); }; ThreadStart act2 = () => { Breakpoint.Define("start2"); log.Add("after start2"); Breakpoint.Define("step act2"); log.Add("after step act2"); Breakpoint.Define("finish2"); }; using (var start1 = new BreakCtrl("start1")) using (var step_act1 = new BreakCtrl("step act1")) using (var finish1 = new BreakCtrl("finish1")) using (var start2 = new BreakCtrl("start2")) using (var step_act2 = new BreakCtrl("step act2")) using (var finish2 = new BreakCtrl("finish2")) { var thr1 = new Thread(act1); thr1.Start(); var thr2 = new Thread(act2); thr2.Start(); start1.Wait(thr1); start2.Wait(thr2); start1.Run(thr1); step_act1.Wait(thr1); step_act1.Run(thr1); finish1.Wait(thr1); start2.Run(thr2); step_act2.Wait(thr2); step_act2.Run(thr2); finish2.Wait(thr2); finish1.Run(thr1); finish2.Run(thr2); thr1.Join(); thr2.Join(); } Assert.AreEqual(4, log.Count); Assert.AreEqual("after start1", log[0]); Assert.AreEqual("after step act1", log[1]); Assert.AreEqual("after start2", log[2]); Assert.AreEqual("after step act2", log[3]); } 


рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрд╕рд╣рдЬ? рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рдЗрд╕рдХреЗ рд╕рд╛рде рд░рдЦрдирд╛ рд╣реЛрдЧрд╛ - рдЖрдЦрд┐рд░рдХрд╛рд░, рдкрд░реАрдХреНрд╖рдг рдХреЗ рдмрд┐рдирд╛ рд░рд┐рдлреИрдХреНрдЯрд░рд┐рдВрдЧ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реИред рдЖрдкрдХреЛ рд╣рдореЗрд╢рд╛ рдЕрдкрдиреЗ рдЖрдк рд╕реЗ рдкрд╣рд▓реЗ рдЬрд╛рдирд╛ рд╣реЛрдЧрд╛ ... рдмреНрд▓рд╛ рдмреНрд▓рд╛ рдмреНрд▓рд╛ред рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдореБрдЭреЗ рдЬрд▓реНрдж рд╣реА рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЕрд╕рдВрднрд╡ рдерд╛ред рдореИрдВ рджреВрд╕рд░реЗ рджрд╕ рд▓рд┐рдЦрд┐рдд рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рд╕рдордЭ рдЧрдпрд╛ред рдЯреЗрд╕реНрдЯ рдкреНрд░рд┐рдп рдФрд░ рдЬрдЯрд┐рд▓ рд╣реИрдВред рд▓реЗрдХрд┐рди ...

рдореБрд╢реНрдХрд┐рд▓ рддреЛ рдЕрдЪреНрдЫреА рд╣реИред рдЖрдЦрд┐рд░рдХрд╛рд░, рдореИрдВ рдЬрдЯрд┐рд▓рддрд╛ рдХреЛ рд╕реБрд▓рдЭрд╛рдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдХреБрдЫ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ред рдереЛрдбрд╝реЗ рдкреНрд░рдпрд╛рд╕ рд╕реЗ рд╣рдореЗрдВ рдпрд╣ рд╕рдорд╛рдзрд╛рди рдорд┐рд▓рд╛:

 public class ThreadTestManager { public ThreadTestManager(TimeSpan timeout, params Action[] threads){тАж} public void Run(params BreakMark[] breaks){тАж} } public class BreakMark { public string Name { get; private set; } public Action ThreadActor { get; private set; } public bool Timeout { get; set; } public BreakMark(string breakName){тАж} public BreakMark(Action threadActor, string breakName){тАж} public static implicit operator BreakMark(string breakName){тАж} } 


рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рдкрд┐рдЫрд▓рд╛ рдкрд░реАрдХреНрд╖рдг рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:

 [TestMethod] public void StopStartThreadsTest_exemple2() { var log = new List<string>(); Action act1 = () => { Breakpoint.Define("before start1"); Breakpoint.Define("start1"); log.Add("after start1"); Breakpoint.Define("step act1"); log.Add("after step act1"); Breakpoint.Define("finish1"); }; Action act2 = () => { Breakpoint.Define("before start2"); Breakpoint.Define("start2"); log.Add("after start2"); Breakpoint.Define("step act2"); log.Add("after step act2"); Breakpoint.Define("finish2"); }; new ThreadTestManager(TimeSpan.FromSeconds(1), act1, act2).Run( "before start1", "before start2", "start1", "step act1", "finish1", "start2", "step act2", "finish2"); Assert.AreEqual(4, log.Count); Assert.AreEqual("after start1", log[0]); Assert.AreEqual("after step act1", log[1]); Assert.AreEqual("after start2", log[2]); Assert.AreEqual("after step act2", log[3]); } 


рдкреНрд░рдмрдВрдзрдХ рдЧреБрдг:
  1. рд╕рднреА рдкреНрд░рддрд┐рдирд┐рдзрд┐рдпреЛрдВ рдХреЛ рдЙрдирдХреЗ рдзрд╛рдЧреЗ рдореЗрдВ рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк рдкрд░ рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
  2. рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯ рдорд╛рд░реНрдХрд░ рдХрд╛рдо рдХреЛ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░рдиреЗ рдХрд╛ рддрд░реАрдХрд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдкреНрд░рд╡реЗрд╢ рджреНрд╡рд╛рд░ рдирд╣реАрдВ, рд▓реЗрдХрд┐рди рдмреНрд░реЗрдХрдкреНрд╡рд╛рдЗрдВрдЯ рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓реЗрдВред рд╢рд╛рдпрдж рдпрд╣ рдХреЗрд╡рд▓ рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯ рдЕрдореВрд░реНрддрддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рд▓рд╛рдЧрдд рд╣реИред рд▓реЗрдХрд┐рди рдПрдХ рд╕рдВрдкрддреНрддрд┐ рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдпрд╛рдж рд░рдЦрдирд╛ рдХрднреА-рдХрднреА рдЖрд╡рд╢реНрдпрдХ рд╣реЛрддрд╛ рд╣реИред
  3. рдЗрд╕реА рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯ рдорд╛рд░реНрдХрд░ рдХреЗ рд▓рд┐рдП рд╕рднреА рдирд┐рдпрдВрддреНрд░рдХ рдбрд┐рд╕реНрдкреИрдЪрд░ рдХреЗ рдХрд╛рдо рдХреЗ рджреМрд░рд╛рди рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдП рдЧрдП рд╣реИрдВред
  4. рдмреНрд░реЗрдХрдкреНрд╡рд╛рдЗрдВрдЯ рдорд╛рд░реНрдХрд░ рдХреЗ рд╕рд╛рде, рдЖрдк рдереНрд░реЗрдб (рдкреНрд░рддрд┐рдирд┐рдзрд┐) рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдпрд╣ рдХрд╛рдо рдХрд░реЗрдЧрд╛ред рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдпрд╣ рд╕рднреА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

     [TestMethod] public void ThreadMarkBreakpointTest_exemple3() { var log = new List<string>(); Action<string> act = name => { Breakpoint.Define("start"); log.Add(name); Breakpoint.Define("finish"); }; Action act0 = () => act("act0"); Action act1 = () => act("act1"); new ThreadTestManager(TimeSpan.FromSeconds(1), act0, act1).Run( new BreakMark(act0, "finish"), new BreakMark(act1, "start"), new BreakMark(act1, "finish")); Assert.AreEqual(2, log.Count); Assert.AreEqual("act0", log[0]); Assert.AreEqual("act1", log[1]); } 
  5. рдкрд░рд┐рднрд╛рд╖рд┐рдд рд╕рдордп рдЬрд┐рд╕рдХреЗ рджреМрд░рд╛рди рд╕рднреА рдСрдкрд░реЗрд╢рди рдХрд┐рдП рдЬрд╛рдиреЗ рдЪрд╛рд╣рд┐рдП - рдЯрд╛рдЗрдордЖрдЙрдЯред рдЬрдм рдкрд╛рд░ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ - рд╕рднреА рдзрд╛рдЧреЗ рдореЛрдЯреЗ рддреМрд░ рдкрд░ рдФрд░ рдмреЗрд░рд╣рдо (рдЧрд░реНрднрдкрд╛рдд) рдмрдВрдж рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВред
  6. рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯ рдорд╛рд░реНрдХрд░ рдХреЗ рд▓рд┐рдП, рдЖрдк рдЕрдкреНрд░рд╛рдкреНрдпрддрд╛ рдХрд╛ рд╕рдВрдХреЗрдд рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ, рдпрджрд┐ рдЖрдк рдпрд╣рд╛рдВ рдирд╣реАрдВ рдорд┐рд▓рддреЗ рд╣реИрдВ, рддреЛ рд╕рд┐рд╕реНрдЯрдо рдЯрд╛рдЗрдордЖрдЙрдЯ рдкрд░ рдмрд╛рд╣рд░ рдирд┐рдХрд▓ рдЬрд╛рдПрдЧрд╛ред рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯ рдХреЛ рдЯреНрд░рд┐рдЧрд░ рдХрд░рдиреЗ рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рд╡рд┐рдлрд▓рддрд╛ рд╣реЛрдЧреАред рдЗрд╕ рддрдВрддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЕрд╡рд░реБрджреНрдз рдХреЗ рддрдереНрдп рдХреЛ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

     [TestMethod] public void Timeout_exemple4() { var log = new List<string>(); Action act = () => { try { while (true) ; } catch (ThreadAbortException) { log.Add("timeout"); } Breakpoint.Define("don't work"); }; new ThreadTestManager(TimeSpan.FromSeconds(1), act).Run( new BreakMark("don't work") { Timeout = true }); Assert.AreEqual("timeout", log.Single()); } 
  7. рдпрджрд┐ рдЖрдк рдкреНрд░рд╡рд╛рд╣ рдХреЛ рд░реЛрдХрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдФрд░ рдЬрд╛рд░реА рдирд╣реАрдВ рд░рдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдЯрд╛рдЗрдордЖрдЙрдЯ рдХреЗ рд╕рд╛рде рдорд╛рд░реНрдХрд░ рдХреЗ рдмрд╛рдж рдЙрдкрдпреБрдХреНрдд рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯ рдорд╛рд░реНрдХрд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

     [TestMethod] public void CatchThread_exemple5() { var log = new List<string>(); Action act0 = () => { bool a = true; while (a) ; Breakpoint.Define("act0"); }; Action act1 = () => { Breakpoint.Define("act1"); log.Add("after act1"); }; new ThreadTestManager(TimeSpan.FromSeconds(1), act0, act1).Run( new BreakMark("act0") { Timeout = true }, "act1"); Assert.IsFalse(log.Any()); } 


рдкреБрдирд╢реНрдЪ: рд╕рдорд╛рдзрд╛рди

Source: https://habr.com/ru/post/In135815/


All Articles