From WinForm private async void btnPrinter_Click(object sender, EventArgs e) { try { CurrentPrinter = new PrinterProcess(); var result = await Task.Run(() => CurrentPrinter.DoProcess()); } catch (System.OperationCanceledException ex) { Trace.WriteLine("Cancelled"); } Trace.WriteLine("Done"); } private void btnIN_Click(object sender, EventArgs e) { CurrentPrinter.CurrentState = Core.STATE.In; } private void btnSTART_Click(object sender, EventArgs e) { CurrentPrinter.CurrentState = Core.STATE.START; } private void btnOUT_Click(object sender, EventArgs e) { CurrentPrinter.CurrentState = Core.STATE.OUT; } private void btnCancel_Click(object sender, EventArgs e) { MyServiceObject.CurrentState = STATE.CANCEL; CurrentPrinter.CurrentState = Core.STATE.CANCEL; } public class PrinterProcess { public STATE CurrentState; public ServerDataList ServerData; public PrinterProcess() { CurrentState = STATE.NotDefine; ServerData = new ServerDataList(); } Task DoIn(CancellationToken token, string text) { return Task.Run(() => { for (var i = 0; i < 10; ++i) { Trace.WriteLine($"{text} loop DataFromServer Code= '{i,22:D22}'"); ServerData.Add(new ServerData() { BestBefore = "12/2023", Code = $"{i,22:D22}", Index = i }); if (token.IsCancellationRequested) { token.ThrowIfCancellationRequested(); return $"{text} cancelled"; } Thread.Sleep(600); } return $"{text} Done"; }); } Task DoStart(CancellationToken token, string text) { return Task.Run(() => { foreach (var item in ServerData) { Trace.WriteLine($"{text} loop PrintTheData {item.ToString()}"); if (token.IsCancellationRequested) { token.ThrowIfCancellationRequested(); return $"{text} cancelled"; } Thread.Sleep(500); } return $"{text} Done"; }); } public async Task DoProcess() { var source = new CancellationTokenSource(); var token = source.Token; Task taskIn = null; Task taskStart = null; Task taskOut = null; try { while (true) { switch (CurrentState) { default: break; case STATE.In: //source = new CancellationTokenSource(); //if (token.Status == TaskStatus.Canceled) taskIn = DoIn(token, "DoIn taskIn"); CurrentState = STATE.NotDefine; break; case STATE.START: string[] startResult = await Task.WhenAll(taskIn); taskStart = DoStart(token, "DoStart taskStart"); CurrentState = STATE.NotDefine; break; case STATE.OUT: string[] outResult = await Task.WhenAll(taskIn, taskStart); foreach (var item in outResult) { Trace.WriteLine($"Task -> {item} ready! Product can move to next machine"); } CurrentState = STATE.NotDefine; break; case STATE.CANCEL: source.Cancel(); Trace.WriteLine($"Cancel State machine"); CurrentState = STATE.NotDefine; break; } // CurrentState = STATE.NotDefine; } } catch (Exception ex) { } finally { } await Task.WhenAll(taskIn, taskStart, taskOut); return $"{taskIn.Result}, {taskStart.Result}, {taskOut.Result}"; } }