private void Worker(AsyncRWLock commLock, CommHelperBase commHelper, LCGen reqLCG, LCGen ansLCG, int pingInterval, CancellationToken token, Action <Exception> pingThreadFailedCallback) { using (var taskRunner = new AsyncRunner()) { var nullBuff = new byte[0]; while (!token.IsCancellationRequested) { commLock.EnterWriteLock(); try { Answer answer = Answer.Invalid; taskRunner.AddTask(() => commHelper.SendRequest(ReqType.Ping, reqLCG.GenerateValue(), nullBuff, 0, 0)); taskRunner.AddTask(commHelper.ReceiveAnswer, (obj) => answer = obj); taskRunner.RunPendingTasks(); if (answer.ansType != AnsType.Pong || answer.seq != ansLCG.GenerateValue()) { throw new Exception(); } } catch (Exception) { //try to resync try { taskRunner.ExecuteTask(commHelper.Resync); } catch (Exception ex) { pingThreadFailedCallback?.Invoke(ex); return; } } finally { commLock.ExitWriteLock(); } try { taskRunner.ExecuteTask(() => Task.Delay(pingInterval, token)); } catch (TaskCanceledException) { return; } catch (Exception ex) { pingThreadFailedCallback?.Invoke(ex); return; } } } }