RJCP.IO.Buffer 0.2.1

dotnet add package RJCP.IO.Buffer --version 0.2.1
NuGet\Install-Package RJCP.IO.Buffer -Version 0.2.1
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="RJCP.IO.Buffer" Version="0.2.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add RJCP.IO.Buffer --version 0.2.1
#r "nuget: RJCP.IO.Buffer, 0.2.1"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install RJCP.IO.Buffer as a Cake Addin
#addin nuget:?package=RJCP.IO.Buffer&version=0.2.1

// Install RJCP.IO.Buffer as a Cake Tool
#tool nuget:?package=RJCP.IO.Buffer&version=0.2.1

RJCP.IO.Buffer

This library contains a set of useful implementations that can be used in multiple different projects.

1. Features

1.1. .NET 4.x AsyncResult

Provides a base class to create your own IAsyncResult methods. It originally debutted at Microsoft's DevBlog - How to Implement IAsyncResult in Another Way, which is no defunct, and no copy by the Wayback Machine was found.

It is recommended to use IAsyncResult only for backwards compatibility, the Task paradigm is much more robust.

Implement your own BeginXXX and EndXXX as:

public IAsyncResult BeginXXX(object par1, object par2, AsyncCallback asyncCallback, object state)
{
    XXXAsyncResult result = new XXXAsyncResult(par1, par2, asyncCallback, state, this, "XXX");
    result.Process();
    return result;


public void EndXXX(IAsyncResult result)
{
    AsyncResult.End(result, this, "XXX");
}

Your own IAsyncResult could look like:

internal class XXXAsyncResult : AsyncResult
{
    private object m_Par1;
    private object m_Par2;

    public XXXAsyncResult(object par1, object par2, AsyncCallback asyncCallback, object state,
                         object owner, string operationId)
        : base(asyncCallback, state, owner, operationId)
    {
        m_Par1 = par1;
        m_Par2 = par2;
    }

    public override void Process()
    {
        Exception exception = null;
        bool synchronous = false;
        try {
            // Do something with m_Par1 and m_Par2. This may be
            // creating a new thread
            ...

            // Indicates that the work is finished without running
            // in the background.
            synchronous = true;
        } catch (System.Exception e) {
            exception = e;
        }
        Complete(exception, synchronous);
    }
}

1.2. Timer Expiry

There are many scenarios where it is useful to maintain timeout scenarios, where the remaining time out from a loop must be maintained for the user. For example, imaging a stream implementing a packet protocol (the Read would return a complete packet), and the underlying transport is byte based. The user might want to wait for a packet with a timeout.

The TimerExpiry makes this easier, by calculating any new timeouts remaining that might be given as a timeout to underlying I/O operations.

It would be instantiated with the user timeout, in milliseconds. And then in a loop, one would check for a CancellationToken, and get the timeout still remaining before calling underlying API.

The exit to the loop is if the TimerExpiry.Expired property is true.

1.3. Circular Buffer

Applications may want to have a bounded buffer when reading from underlying (byte-based) I/O. This is useful for buffered I/O, where data is read (or polled), and copied into a buffer, so that other applications can read out that buffer at their own time.

A practical use case for a Circular Buffer is in the SerialPortStream, where buffers are handed directly to the driver, where not all drivers can handle arbitrary sized buffers.

The implementation uses locking to maintain the state.

The character extension handles the case of character circular buffers, and converting byte buffers to character buffers, especially some very corner cases that there are exceptions because not enough contiguous space might be available when doing the conversion. The implementation will split it up into 16-bit UTF-16 words and split them, abstracting the special case making the buffer look linear.

1.4. Memory Read Buffer, Memory Write Buffer

The MemoryReadBuffer and MemoryWriteBuffer is for I/O operations, that wrap around the CircularBuffer, handling a producer and consumer of the data (one end being the client, the other end being the underlying I/O device). This is used by the SerialPortStream.

2. Release History

2.1. Version 0.2.1

  • Updated from .NET 4.5 to 4.6.2 (DOTNET-827) and .NET Standard 2.1 to .NET 6.0 (DOTNET-936, DOTNET-942, DOTNET-945).

2.2. Version 0.2.0

  • First version, refactored from SerialPortStream
Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Framework net40 is compatible.  net403 was computed.  net45 was computed.  net451 was computed.  net452 was computed.  net46 was computed.  net461 was computed.  net462 is compatible.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on RJCP.IO.Buffer:

Package Downloads
RJCP.SerialPortStream

An independent implementation of System.IO.Ports.SerialPort and SerialStream for better reliability and maintainability.

RJCP.SerialPortStream.Virtual

An independent implementation of System.IO.Ports.SerialPort and SerialStream for better reliability and maintainability. Provides methods to support testing with a virtual native serial port instance.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.2.1 754 3/9/2024
0.2.0 1,259 6/9/2023