Beispiel #1
0
 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();
     }
 }
Beispiel #3
0
 private void Dispose()
 {
     if (TcpClient != null)
     {
         WaitingTasks.Clear();
         if (CancellationTokenSource != null)
         {
             CancellationTokenSource.Cancel();
             CancellationTokenSource = null;
         }
         Dispose(NetworkStream, () => NetworkStream = null);
         Dispose(TcpClient, () => TcpClient         = null);
         OnDisconnected();
     }
 }
Beispiel #4
0
 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();
     }
 }
Beispiel #5
0
        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);
            }
        }
Beispiel #6
0
        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);
        }