private void RunGuardLoop() { int errorCount = 0; while (true) { lock (_ctsLock) { if (_cts == null) { LogInfo("NotStarted"); break; } if (_cts.IsCancellationRequested) { LogInfo("Cancelled"); break; } } try { LoopAction?.Invoke(); LoopTask?.Invoke().Wait(); } catch (Exception e) { errorCount++; if (errorCount > MaxTryFailCount) { LogInfo(string.Format("fail {0} more then max: {1}, exit", errorCount, MaxTryFailCount)); break; } LogEx(e, string.Format("fail time: {0}/{1}, ex:{2}", errorCount, MaxTryFailCount, e.Message)); } try { //Thread.Sleep actually makes current thread to sleep //Task.Delay is a logical delay without blocking the current thread. Task.Delay is a timer based wait mechanism. //In async programming model you should always use Task.Delay() if you want something(continuation) happen after some delay. TaskEx.Delay(LoopSpan).Wait(); } catch (TaskCanceledException) { //await TaskEx.Delay(LoopSpan); should enter here LogInfo(string.Format("Task Canceled => TaskCanceledException")); } catch (AggregateException) { //TaskEx.Delay(LoopSpan).Wait(); should enter here LogInfo(string.Format("Task Canceled => AggregateException")); } catch (Exception) { //should never enter here LogInfo(string.Format("Task Canceled => Exception")); } } }
private void RunGuardLoop() { int errorCount = 0; while (true) { lock (_ctsLock) { if (_cts == null) { LogMessage("NotStarted"); break; } if (_cts.IsCancellationRequested) { LogMessage("Cancelled"); break; } } try { LoopAction?.Invoke(); LoopTask?.Invoke().Wait(); } catch (Exception e) { errorCount++; if (errorCount > MaxTryFailCount) { LogMessage(string.Format("fail {0} more then max: {1}, exit", errorCount, MaxTryFailCount)); break; } LogMessage(string.Format("fail time: {0}/{1}, ex:{2}", errorCount, MaxTryFailCount, e.Message)); } Task.Delay(LoopSpan).Wait(); } }