Skip to content

[API Proposal]: Add rendezvous channel without buffer #94046

Open
@Szer

Description

@Szer

Background and motivation

Problem

let ch = Channel.CreateBounded 1
ch.Write "hi"
Console.WriteLine "consumer received"

The problem is - the last line is a lie, there is no guarantee neither that the consumer received anything, nor there is a consumer in the first place all because that channel has a BUFFER.

Reference

Channels are messaging primitives allowing processes/actors/threads/fiber/jobs/tasks to communicate and synchronize their work and data flow.

Synchronization is achieved by blocking both consumer and receiver until they are ready to communicate and pass data between each other. This is actually a default behaviour of channels in theory (pi-calculus) and practice (Go, Kotlin, F# Hopac, CML)

The problem above is solved in Go precisely as described because default Go channels don't have any buffer and they will block the producer until the consumer is ready and vice versa.

In Kotlin it is achieved by creating Channel with capacity = 0

In .NET you can't create BoundedChannel with capacity=0

  • because capacity can't be lower than 1
  • even if we could, it will be UB what will happen with capacity=0 and BoundedChannelFullMode other than Wait

So I propose to add
Channel.CreateRendezvous()
which will create a channel without any buffers to achieve messaging synchronization and probably some selective messaging (e.g. read multiple channels, read 1, leave all others intact)

API Proposal

namespace System.Threading.Channels;

public static class Channel
{
    public static Channel<T> CreateRendezvous<T>(RendezvousChannelOptions options)
}

API Usage

let fancyChannel = Channel.CreateRendezvous()
do! fancyChannel.WriteAsync 42 // blocked until consumer is ready
Console.WriteLine "consumer received our message!" // not a lie as we know it definitely received

Alternative Designs

Make BoundedChannel work with capacity=0

Risks

N/A

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions