public async Task <CommandError> ExecCmd(DevCommandEnum cmd, params object[] args) { if (!_cmdhandler.TryGetValue(cmd, out var handler)) { AppLogger.Error("Device Command Not Found:"); return(CommandError.CommandNotFound); } var task = new LastCommand { Cmd = cmd, FuncId = handler.FuncId }; if (handler.DontCheckResponse) { task = null; } var isSending = false; //spin lock while (Interlocked.CompareExchange(ref _taskLockTag, CASHelper.LockUsed, CASHelper.LockFree) != CASHelper.LockFree) { } if (_lastCommand != null) { isSending = true; } else { _lastCommand = task; } //free lock Interlocked.CompareExchange(ref _taskLockTag, CASHelper.LockFree, CASHelper.LockUsed); if (isSending) { return(CommandError.SendingCommand); } var buf = new RecycleBuffer(handler.CntSize, _bufMgr); var buffer = buf.Buffer; handler.FillCnt(buffer, args); buffer[0] = handler.FuncId; if (handler.DontCheckResponse) { _clientFrameSender.OnNext(DisposableValue.Create(new ArraySegment <byte>(buffer), buf)); return(CommandError.Success); } _currentTaskCtl = new TaskCompletionSource <CommandError>(); _clientFrameSender.OnNext(DisposableValue.Create(new ArraySegment <byte>(buffer), buf)); #if !DisableDevTimeout ScheduleTimeout(); #endif return(await _currentTaskCtl.Task); }
public async Task <CommandError> ExecCmd(DevCommandEnum cmd, params object[] args) { if (!_cmdhandler.TryGetValue(cmd, out var handler)) { AppLogger.Error("Device Command Not Found:"); return(CommandError.CommandNotFound); } var task = new LastCommand { Cmd = cmd, FuncId = handler.FuncId }; if (handler.DontCheckResponse) { task = null; } var isSending = false; //spin lock while (Interlocked.CompareExchange(ref _taskLockTag, CASHelper.LockUsed, CASHelper.LockFree) != CASHelper.LockFree) { } if (_lastCommand != null) { isSending = true; } else { _lastCommand = task; } //free lock Interlocked.CompareExchange(ref _taskLockTag, CASHelper.LockFree, CASHelper.LockUsed); if (isSending) { return(CommandError.SendingCommand); } var buf = new RecycleBuffer(handler.CntSize, _bufMgr); var buffer = buf.Buffer; var cmdState = handler.FillCnt(buffer, args); buffer[0] = handler.FuncId; if (handler.DontCheckResponse) { _clientFrameSender.OnNext(buf.AsDisposableValue()); handler.HandlerSuccessAsync(cmdState); return(CommandError.Success); } _currentTaskCtl = new TaskCompletionSource <CommandError>(); var loclCtl = _currentTaskCtl; _clientFrameSender.OnNext(buf.AsDisposableValue()); #if !DisableDevTimeout if (_enableTimeout) { ScheduleTimeout(); } #endif try { var waitingTask = loclCtl.Task; var result = await waitingTask; if (result == CommandError.Success) { handler.HandlerSuccessAsync(cmdState); } return(result); } catch (Exception ex) { AppLogger.Error(ex.Message); return(CommandError.Failed); } }