public sealed override ValueTask <int> ReadAsync(Memory <byte> buffer, CancellationToken token) { ValueTask <int> result; if (token.IsCancellationRequested) { #if NETSTANDARD2_1 result = new (Task.FromCanceled <int>(token)); #else result = ValueTask.FromCanceled <int>(token); #endif } else { try { result = new(Read(buffer.Span)); } catch (Exception e) { #if NETSTANDARD2_1 result = new (Task.FromException <int>(e)); #else result = ValueTask.FromException <int>(e); #endif } } return(result); }
protected override ValueTask CloseAsyncCore(ConnectionCloseMethod method, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return(ValueTask.FromCanceled(cancellationToken)); } try { if (method != ConnectionCloseMethod.GracefulShutdown) { // Dispose must be called first in order to cause a connection reset, // as NetworkStream.Dispose() will call Shutdown(Both). _stream.Socket.Dispose(); } _stream.Dispose(); } catch (SocketException socketException) { return(ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(NetworkErrorHelper.MapSocketException(socketException)))); } catch (Exception ex) { return(ValueTask.FromException(ex)); } return(default);
ValueTask IAsyncBinaryWriter.WriteBigIntegerAsync(BigInteger value, LengthFormat lengthFormat, EncodingContext context, string?format, IFormatProvider?provider, CancellationToken token) { ValueTask result; if (token.IsCancellationRequested) { #if NETSTANDARD2_1 result = new (Task.FromCanceled(token)); #else result = ValueTask.FromCanceled(token); #endif } else { result = new(); try { writer.WriteBigInteger(value, lengthFormat, in context, format, provider); } catch (Exception e) { #if NETSTANDARD2_1 result = new (Task.FromException(e)); #else result = ValueTask.FromException(e); #endif } } return(result); }
private unsafe ValueTask <int> ReadAsyncInternal(Memory <byte> destination, CancellationToken cancellationToken = default) { if (!CanRead) { ThrowHelper.ThrowNotSupportedException_UnreadableStream(); } long positionBefore = _filePosition; if (CanSeek) { long len = Length; if (positionBefore + destination.Length > len) { destination = positionBefore <= len? destination.Slice(0, (int)(len - positionBefore)) : default; } // When using overlapped IO, the OS is not supposed to // touch the file pointer location at all. We will adjust it // ourselves, but only in memory. This isn't threadsafe. _filePosition += destination.Length; } (SafeFileHandle.ValueTaskSource? vts, int errorCode) = RandomAccess.QueueAsyncReadFile(_fileHandle, destination, positionBefore, cancellationToken); return(vts != null ? new ValueTask <int>(vts, vts.Version) : (errorCode == 0) ? ValueTask.FromResult(0) : ValueTask.FromException <int>(HandleIOError(positionBefore, errorCode))); }
internal static ValueTask SerializeAsync <T, TWriter>(TWriter writer, string typeId, T obj, CancellationToken token) where TWriter : notnull, IAsyncBinaryWriter { // try to get synchronous writer var bufferWriter = writer.TryGetBufferWriter(); ValueTask result; if (bufferWriter is null) { // slow path - delegate allocation is required and arguments must be packed result = writer.WriteAsync(SerializeToJson, (typeId, obj), token); } else { // fast path - synchronous serialization result = new(); try { Serialize(typeId, obj, bufferWriter); } catch (Exception e) { result = ValueTask.FromException(e); } } return(result);
protected override ValueTask CloseAsyncCore(ConnectionCloseMethod method, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return(ValueTask.FromCanceled(cancellationToken)); } try { if (method != ConnectionCloseMethod.GracefulShutdown) { // Dispose must be called first in order to cause a connection reset, // as NetworkStream.Dispose() will call Shutdown(Both). _socket.Dispose(); } // Since CreatePipe() calls CreateStream(), so _stream should be present even in the pipe case: _stream?.Dispose(); } catch (SocketException socketException) { return(ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(socketException))); } catch (Exception ex) { return(ValueTask.FromException(ex)); } return(default);
ValueTask IAsyncBinaryWriter.WriteAsync <T>(T value, CancellationToken token) { ValueTask result; if (token.IsCancellationRequested) { #if NETSTANDARD2_1 result = new (Task.FromCanceled(token)); #else result = ValueTask.FromCanceled(token); #endif } else { result = new(); try { writer.Write(in value); } catch (Exception e) { #if NETSTANDARD2_1 result = new (Task.FromException(e)); #else result = ValueTask.FromException(e); #endif } } return(result); }
ValueTask IAsyncBinaryWriter.WriteAsync <TArg>(Action <TArg, IBufferWriter <byte> > writer, TArg arg, CancellationToken token) { ValueTask result; if (token.IsCancellationRequested) { #if NETSTANDARD2_1 result = new (Task.FromCanceled(token)); #else result = ValueTask.FromCanceled(token); #endif } else { result = new(); try { writer(arg, this.writer); } catch (Exception e) { #if NETSTANDARD2_1 result = new (Task.FromException(e)); #else result = ValueTask.FromException(e); #endif } } return(result); }
ValueTask IAsyncBinaryReader.SkipAsync(int length, CancellationToken token) { if (length < 0) #if NETSTANDARD2_1 { return(new ValueTask(Task.FromException(new ArgumentOutOfRangeException(nameof(length))))); } #else { return(ValueTask.FromException(new ArgumentOutOfRangeException(nameof(length)))); } #endif if (!stream.CanSeek) { return(SkipSlowAsync(length, token)); } var current = stream.Position; if (current + length > stream.Length) #if NETSTANDARD2_1 { return(new ValueTask(Task.FromException(new EndOfStreamException()))); } #else { return(ValueTask.FromException(new EndOfStreamException())); } #endif stream.Position = length + current; return(new ValueTask()); }
/// <inheritdoc/> public override ValueTask <ValueHttpRequest?> CreateNewRequestAsync(HttpPrimitiveVersion version, HttpVersionPolicy versionPolicy, CancellationToken cancellationToken = default) { if (_writeBuffer.ActiveLength != 0 || _responseContentBytesRemaining != 0) { return(ValueTask.FromException <ValueHttpRequest?>(ExceptionDispatchInfo.SetCurrentStackTrace(new Exception("Unable to create request stream with a request already pending.")))); } if (version.Major != 1) { if (versionPolicy == HttpVersionPolicy.RequestVersionOrLower) { version = HttpPrimitiveVersion.Version11; } return(ValueTask.FromException <ValueHttpRequest?>(ExceptionDispatchInfo.SetCurrentStackTrace(new Exception($"Unable to create request for HTTP/{version.Major}.{version.Minor} with a {nameof(Http1Connection)}.")))); } _writeState = WriteState.Unstarted; _requestIsChunked = true; _responseHasContentLength = false; _responseIsChunked = false; _readingFirstResponseChunk = false; _readFunc = s_ReadResponse; if (Interlocked.Exchange(ref _request, null) is Http1Request request) { request.Init(this, version); } else { request = new Http1Request(this, version); } return(new ValueTask <ValueHttpRequest?>(request.GetValueRequest())); }
ValueTask IAsyncBinaryWriter.WriteAsync(ReadOnlyMemory <char> chars, EncodingContext context, LengthFormat?lengthFormat, CancellationToken token) { ValueTask result; if (token.IsCancellationRequested) { #if NETSTANDARD2_1 result = new (Task.FromCanceled(token)); #else result = ValueTask.FromCanceled(token); #endif } else { result = new(); try { writer.WriteString(chars.Span, in context, lengthFormat: lengthFormat); } catch (Exception e) { #if NETSTANDARD2_1 result = new (Task.FromException(e)); #else result = ValueTask.FromException(e); #endif } } return(result); }
/// <summary> /// Reads bytes from stream and puts them into the buffer /// </summary> /// <param name="buffer">Buffer to read the bytes to.</param> /// <param name="cancellationToken">Token that can be used to cancel this operation.</param> public override ValueTask <int> ReadAsync(Memory <byte> buffer, CancellationToken cancellationToken = default) { if (cancellationToken.IsCancellationRequested) { return(ValueTask.FromCanceled <int>(cancellationToken)); } try { // ReadAsync(Memory<byte>,...) needs to delegate to an existing virtual to do the work, in case an existing derived type // has changed or augmented the logic associated with reads. If the Memory wraps an array, we could delegate to // ReadAsync(byte[], ...), but that would defeat part of the purpose, as ReadAsync(byte[], ...) often needs to allocate // a Task<int> for the return value, so we want to delegate to one of the synchronous methods. We could always // delegate to the Read(Span<byte>) method, and that's the most efficient solution when dealing with a concrete // UnmanagedMemoryStream, but if we're dealing with a type derived from UnmanagedMemoryStream, Read(Span<byte>) will end up delegating // to Read(byte[], ...), which requires it to get a byte[] from ArrayPool and copy the data. So, we special-case the // very common case of the Memory<byte> wrapping an array: if it does, we delegate to Read(byte[], ...) with it, // as that will be efficient in both cases, and we fall back to Read(Span<byte>) if the Memory<byte> wrapped something // else; if this is a concrete UnmanagedMemoryStream, that'll be efficient, and only in the case where the Memory<byte> wrapped // something other than an array and this is an UnmanagedMemoryStream-derived type that doesn't override Read(Span<byte>) will // it then fall back to doing the ArrayPool/copy behavior. return(new ValueTask <int>( MemoryMarshal.TryGetArray(buffer, out ArraySegment <byte> destinationArray) ? Read(destinationArray.Array !, destinationArray.Offset, destinationArray.Count) : Read(buffer.Span))); } catch (Exception ex) { return(ValueTask.FromException <int>(ex)); } }
ValueTask ISupplier <ReadOnlyMemory <byte>, CancellationToken, ValueTask> .Invoke(ReadOnlyMemory <byte> input, CancellationToken token) { ValueTask result; if (token.IsCancellationRequested) { #if NETSTANDARD2_1 result = new (Task.FromCanceled(token)); #else result = ValueTask.FromCanceled(token); #endif } else { result = new(); try { writer.Write(input.Span); } catch (Exception e) { #if NETSTANDARD2_1 result = new (Task.FromException(e)); #else result = ValueTask.FromException(e); #endif } } return(result); }
ValueTask IAsyncBinaryWriter.WriteBigIntegerAsync(BigInteger value, bool littleEndian, LengthFormat?lengthFormat, CancellationToken token) { ValueTask result; if (token.IsCancellationRequested) { #if NETSTANDARD2_1 result = new (Task.FromCanceled(token)); #else result = ValueTask.FromCanceled(token); #endif } else { result = new(); try { writer.WriteBigInteger(in value, littleEndian, lengthFormat); } catch (Exception e) { #if NETSTANDARD2_1 result = new (Task.FromException(e)); #else result = ValueTask.FromException(e); #endif } } return(result); }
public override ValueTask <ValueWebSocketReceiveResult> ReceiveAsync(Memory <byte> buffer, CancellationToken cancellationToken) { try { WebSocketValidate.ThrowIfInvalidState(_state, _disposed, s_validReceiveStates); Debug.Assert(!Monitor.IsEntered(StateUpdateLock), $"{nameof(StateUpdateLock)} must never be held when acquiring {nameof(ReceiveAsyncLock)}"); lock (ReceiveAsyncLock) // synchronize with receives in CloseAsync { ThrowIfOperationInProgress(_lastReceiveAsync.IsCompleted); ValueTask <ValueWebSocketReceiveResult> receiveValueTask = ReceiveAsyncPrivate <ValueWebSocketReceiveResultGetter, ValueWebSocketReceiveResult>(buffer, cancellationToken); if (receiveValueTask.IsCompletedSuccessfully) { _lastReceiveAsync = receiveValueTask.Result.MessageType == WebSocketMessageType.Close ? s_cachedCloseTask : Task.CompletedTask; return(receiveValueTask); } // We need to both store the last receive task and return it, but we can't do that with a ValueTask, // as that could result in consuming it multiple times. Instead, we use AsTask to consume it just once, // and then store that Task and return a new ValueTask that wraps it. (It would be nice in the future // to avoid this AsTask as well; currently it's used both for error detection and as part of close tracking.) Task <ValueWebSocketReceiveResult> receiveTask = receiveValueTask.AsTask(); _lastReceiveAsync = receiveTask; return(new ValueTask <ValueWebSocketReceiveResult>(receiveTask)); } } catch (Exception exc) { return(ValueTask.FromException <ValueWebSocketReceiveResult>(exc)); } }
/// <inheritdoc/> ValueTask IDataTransferObject.WriteToAsync <TWriter>(TWriter writer, CancellationToken token) { ValueTask result; var bufferWriter = writer.TryGetBufferWriter(); if (bufferWriter is null) { result = writer.WriteAsync(Content.AsMemory(), Type.GetEncoding(), null, token); } else { // fast path - serialize synchronously result = new(); try { bufferWriter.WriteString(Content.AsSpan(), Type.GetEncoding()); } catch (Exception e) { #if NETSTANDARD2_1 result = new(Task.FromException(e)); #else result = ValueTask.FromException(e); #endif } } return(result); }
/// <inheritdoc/> public sealed override ValueTask <Connection> ConnectAsync(EndPoint?endPoint, IConnectionProperties?options = null, CancellationToken cancellationToken = default) { if (options == null || !options.TryGet(out DnsEndPointWithProperties? httpOptions)) { return(ValueTask.FromException <Connection>(ExceptionDispatchInfo.SetCurrentStackTrace(new HttpRequestException($"{nameof(SocketsHttpConnectionFactory)} requires a {nameof(DnsEndPointWithProperties)} property.")))); } return(EstablishConnectionAsync(httpOptions !.InitialRequest, endPoint, options, cancellationToken)); }
protected override ValueTask SendBufferAsync(ReadOnlyMemory <byte> buffer, bool isBinary, bool isEOM, CancellationToken cancellationToken) { if (IsClosed()) { return(ValueTask.FromException(new OperationCanceledException())); } return(_webSocket.SendAsync(buffer, isBinary ? WebSocketMessageType.Binary : WebSocketMessageType.Text, isEOM, cancellationToken)); }
public override ValueTask WriteAsync(ReadOnlyMemory <byte> buffer, CancellationToken cancellationToken = default) { long writeOffset = CanSeek ? Interlocked.Add(ref _filePosition, buffer.Length) - buffer.Length : -1; (SafeFileHandle.OverlappedValueTaskSource? vts, int errorCode) = RandomAccess.QueueAsyncWriteFile(_fileHandle, buffer, writeOffset, cancellationToken); return(vts != null ? new ValueTask(vts, vts.Version) : (errorCode == 0) ? ValueTask.CompletedTask : ValueTask.FromException(HandleIOError(writeOffset, errorCode))); }
/// <inheritdoc/> public override ValueTask <int> ReadAsync(Memory <byte> buffer, CancellationToken cancellationToken = default) { if (!CanRead) { return(ValueTask.FromException <int>(new NotSupportedException(SR.NotSupported_UnreadableStream))); } return(ReadAsyncInternal(buffer, cancellationToken)); }
protected override ValueTask <ValueWebSocketReceiveResult> ReceiveBufferAsync(Memory <byte> buffer, CancellationToken cancellationToken) { if (_webSocket.State == WebSocketState.CloseSent) { //Allow receiving the close response. return(_webSocket.ReceiveAsync(buffer, cancellationToken)); } if (IsClosed()) { return(ValueTask.FromException <ValueWebSocketReceiveResult>(new OperationCanceledException())); } return(_webSocket.ReceiveAsync(buffer, cancellationToken)); }
public override ValueTask DisposeAsync() { try { ValueTask vt = _leaveStreamOpen ? new ValueTask(_innerStream.FlushAsync()) : _innerStream.DisposeAsync(); GC.SuppressFinalize(this); return(vt); } catch (Exception exc) { return(ValueTask.FromException(exc)); } }
private static unsafe ValueTask <int> ReadFileScatterAsync(SafeFileHandle handle, MemoryHandle pinnedSegments, int bytesToRead, long fileOffset, CancellationToken cancellationToken) { handle.EnsureThreadPoolBindingInitialized(); SafeFileHandle.OverlappedValueTaskSource vts = handle.GetOverlappedValueTaskSource(); try { NativeOverlapped *nativeOverlapped = vts.PrepareForOperation(Memory <byte> .Empty, fileOffset); Debug.Assert(pinnedSegments.Pointer != null); if (Interop.Kernel32.ReadFileScatter(handle, (long *)pinnedSegments.Pointer, bytesToRead, IntPtr.Zero, nativeOverlapped) == 0) { // The operation failed, or it's pending. int errorCode = FileStreamHelpers.GetLastWin32ErrorAndDisposeHandleIfInvalid(handle); switch (errorCode) { case Interop.Errors.ERROR_IO_PENDING: // Common case: IO was initiated, completion will be handled by callback. // Register for cancellation now that the operation has been initiated. vts.RegisterForCancellation(cancellationToken); break; case Interop.Errors.ERROR_HANDLE_EOF: // logically success with 0 bytes read (read at end of file) case Interop.Errors.ERROR_BROKEN_PIPE: // EOF on a pipe. Callback will not be called. // We clear the overlapped status bit for this special case (failure // to do so looks like we are freeing a pending overlapped later). nativeOverlapped->InternalLow = IntPtr.Zero; vts.Dispose(); return(ValueTask.FromResult(0)); default: // Error. Callback will not be called. vts.Dispose(); return(ValueTask.FromException <int>(Win32Marshal.GetExceptionForWin32Error(errorCode, handle.Path))); } } } catch { vts.Dispose(); throw; } // Completion handled by callback. vts.FinishedScheduling(); return(new ValueTask <int>(vts, vts.Version)); }
protected virtual ValueTask <DbTransaction> BeginDbTransactionAsync(IsolationLevel isolationLevel, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return(ValueTask.FromCanceled <DbTransaction>(cancellationToken)); } try { return(new ValueTask <DbTransaction>(BeginDbTransaction(isolationLevel))); } catch (Exception e) { return(ValueTask.FromException <DbTransaction>(e)); } }
public ValueTask <int> ReceiveAsync(Socket socket, Memory <byte> buffer) { SetBuffer(buffer); if (socket.ReceiveAsync(this)) { return(new ValueTask <int>(this, 0)); } var bytesTransferred = BytesTransferred; var error = SocketError; return(error == SocketError.Success ? new ValueTask <int>(bytesTransferred) : ValueTask.FromException <int>(CreateException(error))); }
private ValueTask <int> CompleteSynchronously() { // Completing synchronously, so we don't need to preserve the // async bits. Reset(); var error = SocketError; if (error == SocketError.Success) { // Return a ValueTask directly, in a no-alloc operation. return(new ValueTask <int>(BytesTransferred)); } // Fail synchronously. return(ValueTask.FromException <int>(new SocketException((int)error))); }
private static Func <ValueTask <MessageBuffer>, ValueTask> CreateHandlerFunc(Func <ValueTask <T>, ValueTask> task) { return(async msgTask => { ValueTask <T> t; try { var msg = await msgTask; t = ValueTask.FromResult(MessageSerializer.Deserialize <T>(msg)); } catch (Exception e) { t = ValueTask.FromException <T>(e); } await task(t); }); }
public override ValueTask WriteAsync(ReadOnlyMemory <byte> buffer, CancellationToken ignored) // token ignored as it comes from SendAsync { BytesWritten += buffer.Length; if (BytesWritten > _contentLength) { return(ValueTask.FromException(new HttpRequestException(SR.net_http_content_write_larger_than_content_length))); } // Have the connection write the data, skipping the buffer. Importantly, this will // force a flush of anything already in the buffer, i.e. any remaining request headers // that are still buffered. HttpConnection connection = GetConnectionOrThrow(); Debug.Assert(connection._currentRequest != null); return(connection.WriteAsync(buffer, async: true)); }
public override ValueTask WriteAsync(ReadOnlyMemory <byte> buffer, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return(ValueTask.FromCanceled(cancellationToken)); } HttpConnection?connection = _connection; if (connection == null) { return(ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new IOException(SR.ObjectDisposed_StreamClosed)))); } if (buffer.Length == 0) { return(default);
public ValueTask UpdateAsync(TEntity item) { try { DbContext.Entry(item).State = EntityState.Modified; return(ValueTask.CompletedTask); } catch (DbUpdateException e) { logger.LogError(e, "Unable To Update State Of {0}", typeof(TEntity).Name); if (e.InnerException is not null) { logger.LogError(e.InnerException, "Update Entity Inner Exception"); } return(ValueTask.FromException(new EntityTransactionException("Unable to update the entity", e))); } }