private void TaskCompletionSourceInvoke(MessageWithId message, string method, object parameter, Type[] types = null) { if (message.HasRequestId && WaitingTasks.TryRemove(message.RequestId, out object tcs)) { var tcsType = tcs.GetType(); (types == null ? tcsType.GetMethod(method) : tcsType.GetMethod(method, types)).Invoke(tcs, new object[] { parameter }); } }
private async Task Dispose(bool waitReceiveTask) { if (NetworkStream != null) { WaitingTasks.Clear(); Dispose(NetworkStream, () => NetworkStream = null); if (waitReceiveTask && ReceiveTcs != null) { await ReceiveTcs.Task; } OnDisconnected(); } }
private void Dispose() { if (TcpClient != null) { WaitingTasks.Clear(); if (CancellationTokenSource != null) { CancellationTokenSource.Cancel(); CancellationTokenSource = null; } Dispose(NetworkStream, () => NetworkStream = null); Dispose(TcpClient, () => TcpClient = null); OnDisconnected(); } }
private async Task Dispose(bool waitReceiveTask) { if (TcpClient != null) { WaitingTasks.Clear(); if (waitReceiveTask && ReceiveTcs != null) { _ = ReceiveTcs.Task; } CancellationTokenSource?.Cancel(); CancellationTokenSource = null; NetworkStream?.Dispose(); TcpClient?.Dispose(); OnDisconnected(); } }
public async Task <R> Invoke(S msgToSend, TimeSpan?timeout = null) { var msgID = Guid.NewGuid(); var msg = JsonConvert.SerializeObject(new ComMessageWrapper <S>() { PayLoad = msgToSend, ID = msgID }); var tcs = new TaskCompletionSource <R>(); WaitingTasks.Add(msgID, tcs); try { var encMsg = Convert.ToBase64String(Encoding.UTF8.GetBytes(msg)); Log.Debug($"Broadcasting message: {encMsg}"); Broadcaster(encMsg); var useTimeout = timeout ?? Timeout; using var timeoutCancellationTokenSource = new CancellationTokenSource(); using var ctReg = CancelOperationToken.Register(timeoutCancellationTokenSource.Cancel); if (await Task.WhenAny(Task.Delay(useTimeout, timeoutCancellationTokenSource.Token), tcs.Task) == tcs.Task) { timeoutCancellationTokenSource.Cancel(); return(tcs.Task.Result); } else { throw new TimeoutException("Task timed out"); } } finally { WaitingTasks.Remove(msgID); } }
internal Object StartPrepareRange(Task task, DataRange range, DataAccess access, DeviceMemorySpace space) { if (_disposed) { throw new ObjectDisposedException(typeof(Data).FullName); } Debug.Assert(WaitingTasks.Count > 0); Debug.Assert(WaitingTasks[0].Task == task); if (!IsRangeValid(range)) { throw new ArgumentOutOfRangeException(); } List <Object> rangeConditions = new List <Object>(); Boolean writing = (access & DataAccess.Write) == DataAccess.Write; Boolean oneWasDirty = false; foreach (DataRangeCopy copyStuckInClusore in DataRangeCopies) { DataRangeCopy copy = copyStuckInClusore; if (range.Intersects(copy.Range)) { List <Object> predecessorConditions = new List <Object>(); // must wait for all conflicting reads/writes if (copy.WritingTask != null) { predecessorConditions.Add(copy.WritingTask); } if (writing) { foreach (Task readingTask in copy.ReadingTasks) { predecessorConditions.Add(readingTask); } } Object rangeCondition = new Object(); DependencyManager.RegisterOperation(rangeCondition); DependencyManager.RegisterContinuation(predecessorConditions, () => { // all conflicting tasks in this copy finished Debug.Assert(copy.WritingTask == null); if (writing) { Debug.Assert(copy.ReadingTasks.Count == 0); } if (range == copy.Range && space == copy.DeviceMemorySpace) { // current copy will be the one used for the task DependencyManager.FinishOperationLocked(rangeCondition); } else { Object copyOrDeleteCondition = null; if (copy.Dirty) { // transfer bytes to host Object readCondition = StartReadBufferRange(copy.Buffer, copy.Range, copy.DeviceMemorySpace.CommandQueue); copyOrDeleteCondition = DependencyManager.ContinueOneWith(readCondition, () => { copy.Dirty = false; }); oneWasDirty = true; } if (writing) { copyOrDeleteCondition = DependencyManager.ContinueOneWith(copyOrDeleteCondition, () => { // copying is not necessary or is finished Debug.Assert(copy.Dirty == false); copy.Buffer.Dispose(); Debug.Assert(DataRangeCopies.Remove(copy)); }); } DependencyManager.RegisterOneContinuation(copyOrDeleteCondition, () => { DependencyManager.FinishOperationLocked(rangeCondition); }); } }); rangeConditions.Add(rangeCondition); } } // dependencies of all conflicting ranges are in rangeConditions Object waitFinishedCondition = WaitingTasks[0].Condition; DependencyManager.RegisterContinuation(rangeConditions, () => { // now there should not be any conflicting ranges anymore // try to find the matching copy DataRangeCopy copy = FindDataRangeCopy(range, space); Object transferCondition = null; if (oneWasDirty || copy == null) { if (copy == null) { Buffer buffer = ComputeManager.Context.CreateBuffer(GetRangeSize(range), BufferFlags.ReadWrite); copy = new DataRangeCopy(buffer, space, range); DataRangeCopies.Add(copy); } // transfer host data to buffer transferCondition = StartWriteBufferRange(copy.Buffer, range, space.CommandQueue); } DependencyManager.RegisterOneContinuation(transferCondition, () => { // range was transferred to buffer or no transfer was necessary Debug.Assert(WaitingTasks.Count > 0); Debug.Assert(WaitingTasks[0].Task == task); Debug.Assert(copy.WritingTask == null); if (writing) { copy.WritingTask = task; copy.Dirty = true; } else { copy.ReadingTasks.Add(task); } WaitingTasks.RemoveAt(0); DependencyManager.FinishOperationLocked(waitFinishedCondition); }); }); return(waitFinishedCondition); }