/// <summary> /// Copy data into the buffers. /// </summary> /// <param name="data">An array containing the data to copy</param> /// <param name="offset">The starting index of the data to copy</param> /// <param name="count">The number of data elements to copy</param> public void CopyDataToBuffer(DataType[] data, int offset, int count) { lock (_lockObject) { EnsureSpaceInInputBuffer(count); CopyDataToInputBuffer(data, offset, count); if (HasAsyncReader && AdvanceToNextOutputBuffer()) { GiveBufferToAsyncReader(OutputBuffer.CreateArraySegment()); } } }
/// <summary> /// Synchronously reads data from the buffer. /// </summary> /// <returns> /// An ArraySegment containing buffered data, or an empty buffer if there is no /// data to read. /// </returns> /// <remarks> /// The ArraySegment remains valid until GetBufferedData/Async is called again. /// After the next call to this method, the buffer in the ArraySegment can be /// reused for future data. /// </remarks> public ArraySegment <DataType> GetBufferedData() { lock (_lockObject) { if (AdvanceToNextOutputBuffer()) { return(OutputBuffer.CreateArraySegment()); } else { SignalBufferEmpty(); return(default(ArraySegment <DataType>)); } } }
/// <summary> /// Asynchronously reads data from the buffer. /// </summary> /// <returns> /// A task that returns an ArraySegment containing buffered data. If there /// is no buffered data, the task does not complete until more data is /// buffered, or the buffers are disposed. /// </returns> /// <remarks> /// The ArraySegment remains valid until GetBufferedData/Async is called again. /// After the next call to this method, the buffer in the ArraySegment can be /// reused for future data. /// </remarks> public Task <ArraySegment <DataType> > GetBufferedDataAsync() { lock (_lockObject) { if (AdvanceToNextOutputBuffer()) { return(Task.FromResult(OutputBuffer.CreateArraySegment())); } else { _getBufferedData = new TaskCompletionSource <ArraySegment <DataType> >(); // We need a local reference to the task here, because SignalBufferEmpty() // could end up calling Dispose(), and that will complete and then clear // _getBufferedData. We still want to return the completed task to the caller // of this method. Task <ArraySegment <DataType> > task = _getBufferedData.Task; SignalBufferEmpty(); return(task); } } }