Skip to content

[Proposal] Async version of CSharp protobuf #3166

@mkosieradzki

Description

@mkosieradzki

I would like to implement support for async/await versions of all methods dealing with I/O.

Rationale

Mixing async and sync code in C# is very inefective thread-wise. It is a good practise to have entire code top-down async, but the worst case-scenario is when synchronous code calls async code like in case of Stream.Read and Stream.Write.

Today the only way to efficiently use protobuf in async code is to copy buffers to the memory and then perform deserialization synchronously. What makes it virtually impossible to use protobuf in streaming scenarios with near-to-constant memory.

Background

Lately there have been many improvements to the TPL to allow more efficient (allocation-wise) handling of many scenarious especially parser-like where most of methods return synchronously. ValueTask and Task.CompletedTask are the most important of those improvements.

High-level plan

  1. Duplicate all I/O-bound methods in the following manner:
    ReturnType MethodName(Arguments)
    to
    async ValueTask MethodNameAsync(Arguments, CancellationToken cancellationToken)

void MethodName(Arguments)
to
async Task MethodNameAsync(Arguments, CancellationToken cancellationToken)

And all references in async methods to those methods with await CalledMethodAsync(..., cancellationToken)

This way we have perfectly correct implementation (but not optimal, especially allocation-wise).

Replace all calls to Stream.Read/Write with proper ReadAsync/WriteAsync

  1. After testing this version start optimizations:
    a. Remove constructs like async await = where possible
    b. Try to use as much of ValueTask and Task.CompletedTask as possible.
    c. Try to inline some async calls to avoid generation of separate state-machines

  2. Modify code-generator to generate async variants.

I would be happy to create PR for this proposal.

However I believe optimization will be a bit longer process, going far beyond this single PR.

Metadata

Metadata

Labels

P3c#enhancementinactiveDenotes the issue/PR has not seen activity in the last 90 days.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions