NamedPipes
System.IO.Pipelines и Named Pipes — это разные технологии в .NET, предназначенные для различных задач ввода-вывода.
System.IO.Pipelines — это высокопроизводительная абстракция для обработки потоков данных внутри
одного процесса. Она оптимизирована для сценариев с большим объёмом данных (парсинг, сетевые протоколы,
сериализация), минимизируя копирование памяти через буферизацию и асинхронную обработку.
System.IO.Pipes (включая NamedPipeServerStream/NamedPipeClientStream) — это механизм
межпроцессного взаимодействия (IPC). Named Pipes используются для обмена данными между разными
процессами на одной машине или по сети.
Аспект System.IO.Pipelines Named Pipes
Назначение Обработка потоков внутри процесса IPC между процессами
Пространство имен System.IO.Pipelines (NuGet) System.IO.Pipes (.NET)
Сценарии HTTP парсинг, JSON, Protocol Buffers Клиент-сервер IPC
Производительность Высокая (нулевое копирование) Средняя (IPC overhead)
Асинхронность Полностью асинхронная Поддерживает async
// Pipelines - внутрипроцессная обработка
var pipe = new Pipe();
await pipe.Writer.WriteAsync(data);
ReadResult result = await pipe.Reader.ReadAsync();
// Nam ed Pipes - между процессами
var server = new Nam edPipeServerStream ("MyPipe");
server.WaitForConnection();
await server.WriteAsync(data); // Другой процесс читает
System.IO.Pipelines и Named Pipes - это одно и тоже
или разное.
Основные различия
[1] [2]
[3] [4]
Сравнение
Практический пример
Pipelines не заменяют Named Pipes, а дополняют их для высоконагруженных сценариев обработки данных.
⁂
System.IO.Pipelines и
Channels
?
Они делают одно и тоже - это взаимодействие внутри процесса
Зачем их два - одинаковых по функциональности ?
System.IO.Pipelines и Channels — это разные абстракции для внутрипроцессного взаимодействия в .NET,
хотя оба работают с потоками данных.
System.IO.Pipelines предназначена для высокопроизводительной обработки байтовых потоков (IO-bound
задачи). Она оптимизирует работу с сырыми данными из сети, файлов или сокетов, минимизируя аллокации
памяти и копирование через буферы и PipeReader/PipeWriter.
System.Threading.Channels — это обобщённые каналы для объектов (object-bound producer-
consumer). Они потокобезопасны и подходят для передачи готовых объектов (Channel<T>), блокирующих
чтение/запись с bounded/unbounded режимами.
Аспект System.IO.Pipelines Channels
Данные Байты (ReadOnlySequence<byte>) Объекты (T)
Сценарии Парсинг HTTP/JSON, сетевой IO Producer-consumer, очереди задач
Thread-safety Не потокобезопасна (однопоточная) Полностью потокобезопасна
Backpressure Через буферы и AdvanceTo Через bounded capacity
Пространство имён System .IO.Pipelines System .Threading.Channels
// Pipelines - парсинг байтов из сокета
var pipe = new Pipe();
await FillPipeAsync(socket, pipe.Writer); // IO из сети
await ParseLinesAsync(pipe.Reader); // Парсинг без копирования
// Channels - очередь объектов между задачами
var channel = Channel.CreateBounded<string>(10);
channel.Writer.WriteAsync("m essage"); // Producer
await foreach (var m sg in channel.Reader.ReadAllAsync()) // Consum er
[2] [1]
ТОгда чем отличается
Основные различия
[11] [12]
[13] [14]
Сравнение
Практические сценарии
Они дополняют друг друга: Pipelines для низкоуровневого IO, Channels для высокоуровневой координации
объектов. Часто используются вместе.
⁂
Какой абстракции использовать для взаимодействия этих двух потоков ?
System.IO.Pipelines и
Channels
?
Channels — это рекомендуемая абстракция для взаимодействия между двумя BackgroundService в .NET,
так как они потокобезопасны и идеальны для producer-consumer паттерна между сервисами.
Pipelines подходят только если данные — это сырые байты с высокой нагрузкой (например, парсинг из сети),
но для типичных задач (сообщения, объекты) Channels проще и эффективнее.
Полностью thread-safe для записи из одного сервиса и чтения из другого.
Встроенная поддержка backpressure через bounded capacity.
Официальный пример MS для BackgroundService использует именно Channel для очередей задач.
// Общий Channel (регистрируется как Singleton)
services.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>();
// ProducerService
public class ProducerService : BackgroundService
{
private readonly IBackgroundTaskQueue _queue;
protected override async Task ExecuteAsync(CancellationToken ct)
{
while (!ct.IsCancellationRequested)
{
await _queue.QueueBackgroundWorkItem Async(async token => {
// Обработка данных
await Task.Delay(1000, token);
});
await Task.Delay(5000, ct);
}
}
}
// Consum erService
public class Consum erService : BackgroundService
{
[14] [13]
Допустим у нас есть два BackgroundServices
[21] [22]
[22]
Почему Channels
[21]
Пример реализации
private readonly IBackgroundTaskQueue _queue;
protected override async Task ExecuteAsync(CancellationToken ct)
{
while (!ct.IsCancellationRequested)
{
var workItem = await _queue.DequeueAsync(ct);
await workItem (ct); // Выполнение задачи от Producer
}
}
}
// BackgroundTaskQueue (Channel)
public interface IBackgroundTaskQueue
{
ValueTask QueueBackgroundWorkItem Async(Func<CancellationToken, ValueTask> workItem );
ValueTask<Func<CancellationToken, ValueTask>> DequeueAsync(CancellationToken ct);
}
public class BackgroundTaskQueue : IBackgroundTaskQueue
{
private readonly Channel<Func<CancellationToken, ValueTask>> _queue =
Channel.CreateBounded<Func<CancellationToken, ValueTask>>(
new BoundedChannelOptions(100) { FullMode = BoundedChannelFullMode.Wait });
public ValueTask QueueBackgroundWorkItem Async(Func<CancellationToken, ValueTask> work
_queue.Writer.WriteAsync(workItem );
public ValueTask<Func<CancellationToken, ValueTask>> DequeueAsync(CancellationToken ct
_queue.Reader.ReadAsync(ct);
}
Регистрируйте сервисы в `Program .cs`: `services.AddHostedService<ProducerService>(); se
⁂
System.IO.Pipelines и
Channels
А для IPC у нс есть одна абстракция
NAmedPipes
?
Да, ваша логика верна, но с уточнениями по IPC.
Получается что для взаимодействия в одном процессе
у нас есть две абстракции
Две абстракции для разных задач:
Channels (System .Threading.Channels) — для передачи объектов между потоками/сервисами
(producer-consumer).
Pipelines (System .IO.Pipelines) — для обработки байтовых потоков с высокой
производительностью (парсинг, протоколы).
Две абстракции в System.IO.Pipes:
Named Pipes (Nam edPipeServerStream /ClientStream ) — сетевое IPC, дуплекс, несколько
клиентов.
Anonymous Pipes (Anonym ousPipeServerStream /ClientStream ) — локальное IPC между
связанными процессами (родитель-дочерний), односторонние, не для сети.
Уровень Абстракции Данные Thread-safe Сценарии
Внутри процесса Channels T (объекты) ✅ BackgroundService, очереди
Pipelines byte[] ❌ HTTP парсинг, Protocol Buffers
IPC (локальное) Anonymous Pipes Stream ❌ Родитель → дочерний процесс
IPC (сетевое) Named Pipes Stream ❌ Процессы по сети
Вывод: Для BackgroundService в одном процессе — Channels. Для байтовых протоколов — Pipelines.
Для IPC между разными процессами — Named/Anonymous Pipes.
⁂
TCP/IP не входит ни в одну из перечисленных категорий (Channels, Pipelines, Named Pipes). Это
сетевой протокол стека, а не абстракция .NET для IO/IPC.
Абстракция .NET Уровень TCP/IP поддержка
Channels Внутри процесса ❌ Нет
Pipelines Внутри процесса ✅ Да — для обработки байтов над TCP сокетами
Named Pipes IPC (процессы) ❌ Нет (свой протокол)
Внутри процесса (один процесс)
[31]
[32]
Межпроцессное взаимодействие (IPC)
[33] [34]
[33]
Правильная картина
[31] [33]
TCP/IP - в какую категорию входит ?
Правильная классификация
TCP/IP работает на уровне Socket/NetworkStream (System .Net.Sockets), а System.IO.Pipelines
применяется поверх него для парсинга данных:
// TCP сокет + Pipelines
var socket = new Socket(...);
var stream = new NetworkStream (socket);
var pipe = new Pipe();
// Pipelines обрабатывает байты из TCP
await FillPipeAsync(stream , pipe.Writer);
await ProcessLinesAsync(pipe.Reader); // Парсинг HTTP/JSON
Kestrel (ASP.NET Core) использует именно Pipelines поверх TCP сокетов для высокопроизводительного
HTTP.
TCP Socket → System .IO.Pipelines → Парсинг протокола (HTTP/gRPC)
↓
BackgroundService ← Channels ← Producer/Consum er (объекты)
Nam edPipeStream → IPC между процессами
TCP/IP — это транспорт, Pipelines — обработка байтов из этого транспорта.
⁂
Да, для сетевого IPC через Named Pipes обязательно нужны сервер и клиент.
Named Pipes работают по клиент-серверной модели:
Сервер (Nam edPipeServerStream ) Клиент (Nam edPipeClientStream )
↓ ↓
1. Создает pipe "MyPipe" 2. Подключается к "MyPipe"
2. WaitForConnection() 2. Connect()
3. Обмен данными 3. Обмен данными
Где используется TCP/IP в .NET
[41] [42]
Итоговая картина
[41]
Для (IPC (сетевое) Named Pipes) необходим сервер и
клиент ?
Архитектура Named Pipes
Роль Класс Обязанности
Сервер Nam edPipeServerStream Создает именованный канал, ждет подключений
Клиент Nam edPipeClientStream Подключается к существующему каналу
// СЕРВЕР
var server = new Nam edPipeServerStream ("MyPipe", PipeDirection.InOut);
Console.WriteLine("Сервер ждет подключения...");
server.WaitForConnection(); // БЛОКИРУЕТСЯ до клиента
await server.WriteAsync(Encoding.UTF8.GetBytes("Hello"));
// КЛИЕНТ (в другом процессе)
var client = new Nam edPipeClientStream (".", "MyPipe", PipeDirection.InOut);
client.Connect(); // Подключается к серверу
var buffer = new byte[^6_1024];
await client.ReadAsync(buffer); // Получает "Hello"
Без сервера клиент не найдет pipe (ошибка "pipe not found").
Без клиента сервер будет висеть на WaitForConnection().
Это фундаментальное отличие от Channels (peer-to-peer в одном процессе).
⁂
Да, NamedPipeServerStream может обслуживать несколько клиентов одновременно.
Сервер создает несколько экземпляров одного именованного канала с помощью параметра
m axNum berOfServerInstances:
// Сервер поддерживает до 4 клиентов одновременно
var server = new Nam edPipeServerStream (
"MyPipe",
PipeDirection.InOut,
4, // Максимум 4 клиента одновременно
PipeTransm issionMode.Byte,
PipeOptions.Asynchronous);
Обязательные роли
Минимальный пример
[49] [50]
И Такой Сервер может обслуживать несколько
Клиентов ?
Как это работает
Модель Описание Код
Многопоточная Поток на каждый клиент Task.Run(ProcessClientAsync(pipe))
Однопоточная Async I/O с OVERLAPPED await pipe.WaitForConnectionAsync() в цикле
public async Task StartServerAsync()
{
while (!stoppingToken.IsCancellationRequested)
{
var pipe = new Nam edPipeServerStream ("MyPipe", PipeDirection.InOut,
Nam edPipeServerStream .MaxAllowedServerInstances,
PipeTransm issionMode.Byte, PipeOptions.Asynchronous);
await pipe.WaitForConnectionAsync(stoppingToken);
// Новый поток/задача для клиента
_ = Task.Run(() => ProcessClientAsync(pipe), stoppingToken);
}
}
private async Task ProcessClientAsync(Nam edPipeServerStream pipe)
{
try
{
// Обработка клиента
var buffer = new byte[^7_1024];
int bytesRead = await pipe.ReadAsync(buffer, 0, buffer.Length);
await pipe.WriteAsync(buffer, 0, bytesRead);
}
finally
{
pipe.Dispose();
}
}
Ограничение: По умолчанию максимум 254 клиента на pipe name (MaxAllowedServerInstances). Каждый
клиент получает отдельный экземпляр pipe, сервер управляет ими параллельно.
⁂
Модели обработки нескольких клиентов
Пример многопоточного сервера
[58] [59]
Да, именно так! Named Pipes идеально подходят для архитектуры "Звезда с центральным сервером-
маршрутизатором".
Клиент1
↑
Клиент2 ←→ Nam edPipeServerStream ← КлиентN
↓ (Маршрутизатор)
Клиент3
Сервер получает сообщения от клиентов и пересылает их другим клиентам по ID/именам.
public class Nam edPipeRouter : BackgroundService
{
private readonly ConcurrentDictionary<string, Nam edPipeServerStream > _clients = new
private readonly Sem aphoreSlim _sem aphore = new(1, 1);
protected override async Task ExecuteAsync(CancellationToken ct)
{
while (!ct.IsCancellationRequested)
{
var pipe = new Nam edPipeServerStream ("RouterPipe", PipeDirection.InOut,
Nam edPipeServerStream .MaxAllowedServerInstances);
await pipe.WaitForConnectionAsync(ct);
_ = Task.Run(() => HandleClientAsync(pipe, ct), ct);
}
}
private async Task HandleClientAsync(Nam edPipeServerStream pipe, CancellationToken c
{
var buffer = new byte[^8_4096];
string clientId = Guid.NewGuid().ToString("N")[..8]; // ID клиента
_clients.TryAdd(clientId, pipe);
try
{
while (pipe.IsConnected)
{
int bytes = await pipe.ReadAsync(buffer, ct);
if (bytes == 0) break;
Таким образом мы можем получить Архитектуру
Звезда с Серером Звезда и обслуживать множество
Клиентов, которые (Клиенты) взимодействуют друг с
другом. А Сервер выступает как Маршрутизатор.
Архитектура "Звезда" через Named Pipes
Реализация маршрутизатора
string m essage = Encoding.UTF8.GetString(buffer, 0, bytes);
var parts = m essage.Split(':', 2); // "targetClientId:payload"
if (parts.Length == 2)
await BroadcastToClientAsync(parts[^8_0], parts[^8_1], ct);
}
}
finally
{
_clients.TryRem ove(clientId, out _);
pipe.Dispose();
}
}
private async Task BroadcastToClientAsync(string targetId, string payload, Cancellati
{
if (_clients.TryGetValue(targetId, out var targetPipe) && targetPipe.IsConnected
{
var data = Encoding.UTF8.GetBytes(payload);
await targetPipe.WriteAsync(data, ct);
}
}
}
Централизованный контроль — сервер знает всех клиентов
До 254 одновременных клиентов на pipe name
Маршрутизация по ID — клиент отправляет Client123:Hello → сервер пересылает Client123
Многопоточность — каждый клиент в отдельной Task
Это стандартный паттерн для чат-серверов, мониторинга процессов, микросервисного IPC. Клиенты не
взаимодействуют напрямую — только через сервер-маршрутизатор.
⁂
Да, архитектура "Звезда" с Named Pipes отлично подходит для нескольких приложений .NET Aspire!
Это нативный, высокопроизводительный IPC без внешних зависимостей.
Aspire (дистрибутивный оркестратор) запускает каждый проект как отдельный процесс с Service Discovery
— идеально для Named Pipes.
Преимущества для "Звезды"
[68]
[69] [70]
Это будет удобно использовать несколько
Приложений с хостом NetAspire, которые
взаимодествуют между собой.
Преимущества в .NET Aspire
[80]
Aspire AppHost
├── RouterService (Nam edPipeServerStream ) ← Центральный маршрутизатор
├── WorkerApp1 (Клиент)
├── WorkerApp2 (Клиент)
└── DashboardApp (Клиент)
# AppHost.csproj или Program .cs
.AddProject<Projects.RouterService>("router")
.AddProject<Projects.Worker1>("worker1")
.AddProject<Projects.Worker2>("worker2")
// Program .cs
builder.AddServiceDefaults();
builder.Services.AddHostedService<Nam edPipeRouter>();
var app = builder.Build();
app.Run();
// appsettings.json или ServiceDiscovery
builder.Services.AddServiceDiscovery();
builder.AddServiceDefaults();
// Подключение к роутеру
var routerConnectionString = builder.Configuration["ConnectionStrings:Router"]
?? "\\\\.\\pipe\\AspireRouterPipe";
Aspire автоматически регистрирует сервисы:
// Клиент подключается через имя сервиса
var routerNam e = "router"; // Из Aspire
var pipeNam e = $"\\\\{Environm ent.MachineNam e}\\pipe\\{routerNam e}";
var client = new Nam edPipeClientStream (".", pipeNam e, PipeDirection.InOut);
Интеграция с Aspire
1. RouterService (маршрутизатор)
2. В RouterService
3. Клиенты (Worker1, Worker2)
Service Discovery в Aspire
1. Aspire запускает RouterService + Worker1 + Worker2
2. Router создает pipe "AspireRouterPipe" (m axInstances=10)
3. Worker1/2 регистрируются: "Worker1:ready"
4. Worker1 → Router: "Worker2:process-this-data"
5. Router → Worker2: "process-this-data"
Подход Производительность Сложность Aspire интеграция
Named Pipes ⭐⭐⭐⭐⭐ (нативно) Низкая ✅ Service Discovery
gRPC ⭐⭐⭐⭐ Средняя ✅ Встроено
RabbitMQ ⭐⭐⭐ Высокая Через контейнер
Redis Pub/Sub ⭐⭐⭐ Средняя Через контейнер
Named Pipes — лучший выбор для локального кластера Aspire: 0ms latency, без сети, thread-safe.
Запускайте aspire run — и вся "Звезда" готова!
⁂
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFram ework>net10.0</TargetFram ework>
<Nullable>enable</Nullable>
<Im plicitUsings>enable</Im plicitUsings>
</PropertyGroup>
<Item Group>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.ServiceDiscovery" Version="8.0.0" />
<PackageReference Include="Aspire.Hosting" Version="8.0.0" />
</Item Group>
</Project>
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
var builder = DistributedApplication.CreateBuilder(args);
Полный workflow
Сравнение альтернатив в Aspire
[80]
Полный пример BackgroundService с NamedPipeServerStream для Aspire
1. RouterService.csproj
2. Program.cs (RouterService)
// Регистрация BackgroundService
builder.Services.AddHostedService<Nam edPipeRouterService>();
var app = builder.Build();
await app.RunAsync();
using System .IO.Pipes;
using System .Text;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
public class Nam edPipeRouterService : BackgroundService
{
private readonly ILogger<Nam edPipeRouterService> _logger;
private readonly CancellationTokenSource _cts = new();
public Nam edPipeRouterService(ILogger<Nam edPipeRouterService> logger)
{
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInform ation(" Nam edPipe Router запущен на pipe: AspireRouterPipe")
while (!stoppingToken.IsCancellationRequested)
{
try
{
// Создаем сервер с поддержкой множественных клиентов
var pipeServer = new Nam edPipeServerStream (
"AspireRouterPipe",
PipeDirection.InOut,
Nam edPipeServerStream .MaxAllowedServerInstances, // До 254 клиентов
PipeTransm issionMode.Byte,
PipeOptions.Asynchronous | PipeOptions.WriteThrough);
_logger.LogInform ation(" Ожидание подключения клиента...");
await pipeServer.WaitForConnectionAsync(stoppingToken);
_logger.LogDebug("✅ Клиент подключен: {ClientId}",
pipeServer.SafePipeHandle.DangerousGetHandle());
// Обработка клиента в отдельной задаче
_ = Task.Run(() => HandleClientAsync(pipeServer, stoppingToken), stopping
}
catch (OperationCanceledException)
{
break;
}
catch (Exception ex)
{
_logger.LogError(ex, "❌ Ошибка сервера Nam edPipe");
3. NamedPipeRouterService.cs (BackgroundService)
await Task.Delay(1000, stoppingToken);
}
}
}
private async Task HandleClientAsync(Nam edPipeServerStream pipeServer, Cancellation
{
var buffer = new byte[^10_4096];
try
{
while (pipeServer.IsConnected && !ct.IsCancellationRequested)
{
// Чтение сообщения от клиента
int bytesRead = await pipeServer.ReadAsync(buffer, 0, buffer.Length, ct);
if (bytesRead == 0) break;
string m essage = Encoding.UTF8.GetString(buffer, 0, bytesRead);
_logger.LogInform ation(" Получено: {Message}", m essage);
// Простая маршрутизация (эхо обратно)
var response = $"Echo: {m essage}";
var responseBytes = Encoding.UTF8.GetBytes(response);
await pipeServer.WriteAsync(responseBytes, 0, responseBytes.Length, ct);
_logger.LogInform ation(" Отправлено: {Response}", response);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "❌ Ошибка обработки клиента");
}
finally
{
pipeServer.Dispose();
_logger.LogInform ation(" Клиент отключен");
}
}
public override async Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInform ation(" Остановка Nam edPipe Router...");
_cts.Cancel();
await base.StopAsync(cancellationToken);
}
}
var builder = DistributedApplication.CreateBuilder(args);
builder.AddProject<Projects.RouterService>("router");
builder.Build().Run();
4. AppHost (AppHost.csproj)
// Nam edPipeClientService
public async Task SendMessageAsync(string m essage)
{
using var client = new Nam edPipeClientStream (".", "AspireRouterPipe", PipeDirectio
await client.ConnectAsync(5000); // Tim eout 5s
var data = Encoding.UTF8.GetBytes(m essage);
await client.WriteAsync(data);
// Чтение ответа
var buffer = new byte[^10_4096];
int bytes = await client.ReadAsync(buffer);
var response = Encoding.UTF8.GetString(buffer, 0, bytes);
Console.WriteLine($"Ответ от роутера: {response}");
}
dotnet run --project AppHost
Результат:
Nam edPipe Router запущен на pipe: AspireRouterPipe
Ожидание подключения клиента...
✅ Клиент подключен
Получено: Hello from Worker1
Отправлено: Echo: Hello from Worker1
Клиент отключен
Этот код готов к production: async, cancellation-aware, logging, multiple clients. Добавьте
ConcurrentDictionary для маршрутизации между клиентами!
⁂
MassTransit + Aspire = идеальный IPC для микросервисов. Aspire автоматически настраивает брокеры
(RabbitMQ/PostgreSQL).
AspireSolution/
├── Contracts/ # Общие контракты сообщений
├── ApiService/ # Publisher
├── WorkerService/ # Consum er
5. Клиент (другое Aspire-приложение)
Запуск в Aspire
[97] [98]
Полная интеграция MassTransit в .NET Aspire (IPC)
Структура решения
├── AppHost/ # Оркестратор
└── ServiceDefaults/
// Contracts.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFram ework>net10.0</TargetFram ework>
</PropertyGroup>
</Project>
// OrderCreated.cs
public record OrderCreated(
Guid OrderId,
string Custom erId,
decim al Am ount,
DateTim e CreatedAt);
// ServiceDefaults.csproj
<Project Sdk="Microsoft.NET.Sdk">
<Item Group>
<PackageReference Include="Aspire" Version="8.2.0" />
</Item Group>
</Project>
// Program .cs
public static class Extensions
{
public static IServiceCollection AddServiceDefaults(this IServiceCollection services
{
services.AddServiceDiscovery();
return services;
}
}
// ApiService.csproj
<PackageReference Include="MassTransit.RabbitMQ.AspNetCore" Version="8.2.5" />
<ProjectReference Include="..\Contracts\Contracts.csproj" />
<ProjectReference Include="..\ServiceDefaults\ServiceDefaults.csproj" />
// Program .cs
var builder = WebApplication.CreateBuilder(args);
builder.AddServiceDefaults();
// MassTransit с RabbitMQ из Aspire
1. Contracts (Message Contracts)
2. ServiceDefaults (общая настройка)
3. ApiService (Publisher)
builder.Services.AddMassTransit(x =>
{
x.UsingRabbitMq((context, cfg) =>
{
cfg.Host("rabbitm q"); // Имя ресурса из Aspire
});
});
var app = builder.Build();
app.MapPost("/orders", async (IPublishEndpoint publish, OrderCreated order) =>
{
await publish.Publish(order);
return Results.Ok();
});
app.Run();
// WorkerService.csproj
<PackageReference Include="MassTransit.RabbitMQ" Version="8.2.5" />
<ProjectReference Include="..\Contracts\Contracts.csproj" />
<ProjectReference Include="..\ServiceDefaults\ServiceDefaults.csproj" />
// Program .cs
var builder = Host.CreateApplicationBuilder(args);
builder.AddServiceDefaults();
builder.Services.AddMassTransit(x =>
{
x.AddConsum er<OrderConsum er>();
x.UsingRabbitMq((context, cfg) =>
{
cfg.Host("rabbitm q");
cfg.ReceiveEndpoint("order-queue", e =>
{
e.ConfigureConsum er<OrderConsum er>(context);
});
});
});
var host = builder.Build();
await host.RunAsync();
// OrderConsum er.cs
public class OrderConsum er : IConsum er<OrderCreated>
{
private readonly ILogger<OrderConsum er> _logger;
public OrderConsum er(ILogger<OrderConsum er> logger)
{
_logger = logger;
4. WorkerService (Consumer)
}
public Task Consum e(Consum eContext<OrderCreated> context)
{
_logger.LogInform ation("✅ Заказ обработан: OrderId={OrderId}, Custom er={Custom e
context.Message.OrderId, context.Message.Custom erId);
return Task.Com pletedTask;
}
}
// AppHost.csproj
<PackageReference Include="Aspire.Hosting.RabbitMQ" Version="8.2.0" />
<PackageReference Include="Aspire.Hosting.PostgreSql" Version="8.2.0" />
// Program .cs
var builder = DistributedApplication.CreateBuilder(args);
// RabbitMQ для MassTransit
var rabbitm q = builder.AddRabbitMQ("rabbitm q")
.WithJsonSerializer()
.WithManagem entPort(); // RabbitMQ Dashboard
// PostgreSQL (альтернатива для SQL Transport)
var postgres = builder.AddPostgres("postgres")
.WithDataVolum e()
.WithTcpPortMapping();
// Проекты
builder.AddProject<Projects.ApiService>("api")
.WithReference(rabbitm q)
.WithExternalHttpEndpoints();
builder.AddProject<Projects.WorkerService>("worker")
.WithReference(rabbitm q);
builder.Build().Run();
dotnet run --project AppHost
Dashboard Aspire: https://localhost:18888
RabbitMQ UI: http://localhost:15672 (user:guest/pass:guest)
API: POST https://localhost:5001/orders
{
"orderId": "guid",
"custom erId": "client123",
5. AppHost (Оркестрация)
6. Запуск и тест
"am ount": 100.50
}
// В ApiService/WorkerService
builder.Services.AddMassTransit(x =>
{
x.UsingSqlServer((context, cfg) =>
{
cfg.ConnectionString = postgres.GetConnectionString();
cfg.ReceiveEndpoint("order-queue", e => { });
});
});
Результат: Масштабируемый IPC с retry, dead-letter, monitoring из коробки. Aspire управляет
инфраструктурой автоматически!
⁂
MassTransit и Named Pipes — разные уровни IPC в Aspire: MassTransit для распределённых систем,
Named Pipes для локального высокопроизводительного обмена.
Критерий Named Pipes MassTransit
Архитектура Звезда (сервер+клиенты) Pub/Sub, Request/Reply
Транспорт Локальные pipes (Windows) RabbitMQ, PostgreSQL, Azure SB
Latency 0-1ms (память) 10-100ms (брокер)
Throughput 10k+ msg/s 1k-10k msg/s
Надёжность Нет (volatile) Retry, DLQ, Sagas
Масштабирование Локальная машина Кластер, облако
Aspire интеграция Ручная (pipe name) Авто (AddRabbitMQ)
Сложность Низкая (Stream) Высокая (контракты, consumer)
SQL Transport (без RabbitMQ)
[103]
Разница MassTransit и Named Pipes для IPC в
Aspire
Сравнение
[111]
Named Pipes в Aspire:
Локальный кластер (1 машина)
- Мониторинг процессов
- Реал-тайм дашборды
- Внутри VM/container
Производительность: 100MB+/s, без брокера.
MassTransit в Aspire:
Распределённый кластер
- Микросервисы
- Event Sourcing
- Сагi-оркестрация
Функции: partitioning, filtering, healthchecks.
Метрика Named Pipes MassTransit
Connections 254 max Неограниченно
Monitoring Ручной logging ✅ Aspire + RabbitMQ UI
Resilience ❌ Нет retry ✅ Circuit Breaker
Discovery Ручной pipe name ✅ Авто ServiceDiscovery
Для ваших BackgroundService в Aspire:
1. **Nam ed Pipes** — если:
- Локальная машина
- Реал-тайм (<10m s)
- Простая "Звезда"
2. **MassTransit** — если:
- Много контейнеров
- Нужны retry/DLQ
- Будущий кластер
Гибрид: Named Pipes для локального + MassTransit для cross-host IPC. Aspire делает MassTransit
проще, но Named Pipes быстрее в 10x для local!
⁂
Когда использовать
[112]
[111] [113]
Aspire Dashboard сравнение
Рекомендация по сценарию
[111]
. https://habr.com/ru/articles/464921/
. https://stackoverflow.com/questions/77952130/whats-the-different-system-io-pipes-namespace-and-syste
m-io-pipelines-namespace
. https://learn.microsoft.com/ru-ru/dotnet/api/system.io.pipes.namedpipeserverstream?view=net-8.0
. https://learn.microsoft.com/ru-ru/dotnet/standard/io/how-to-use-named-pipes-for-network-interprocess-co
mmunication
. https://habr.com/ru/articles/81067/
. https://www.reddit.com/r/csharp/comments/x9eya7/how_to_connect_two_programs_running_on_the_same/
. https://rabrain.ru/special/handbook/go/packages/io/types/
. https://www.aldpro.ru/professional/ALSE_Module_13/processes.html
. https://platformv.sbertech.ru/docs/public/SLO/9.6.0/common/documents/administration-guide/operational-a
ctions-5-kernel.html
. https://identityblitz.ru/wp-content/uploads/2022/07/Руководство_по_интеграции_5.7.pdf
. https://habr.com/ru/companies/microsoft/articles/423105/
. https://learn.microsoft.com/ru-ru/dotnet/standard/io/pipelines
. https://www.reddit.com/r/dotnet/comments/ixja8w/use_systemiopipelines_and_systemthreadingchannels/
. https://itnext.io/use-system-io-pipelines-and-system-threading-channels-apis-to-boost-performance-832d
7ab7c719
. https://yarfullstack.com/post/2018-07/net-core-pipelines-and-channel/
. https://learn.microsoft.com/ru-ru/shows/on-dotnet/high-performance-io-with-systemiopipelines
. https://pcnews.ru/blogs/[perevod]_systemiopipelines_vysokoeffektivnyj_io_v_net-858406.html
. https://habr.com/ru/companies/microsoft/articles/423105/comments/
. https://csharp-help.ru/2025/07/20/использование-system-io-pipelines-для-высокопроизво/
. https://www.reddit.com/r/dotnet/comments/1ga36zt/most_underrated_technology_in_net/
. https://learn.microsoft.com/ru-ru/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-10.0
. https://www.reddit.com/r/dotnet/comments/ixja8w/use_systemiopipelines_and_systemthreadingchannels/
. https://devdotnet.org/post/sozdanie-seti-vpn-na-baze-softether-wireguard-s-shadowsocks/
. https://learn.microsoft.com/ru-ru/dotnet/core/extensions/scoped-service
. https://ru.stackoverflow.com/questions/1419361/asp-net-core-как-реализовать-сервис-обновляющий-данные
-каждые-3-секунды
. https://habr.com/ru/articles/321502/
. https://www.cyberforum.ru/blogs/2408863/blog10419.html
. https://ru.stackoverflow.com/questions/1294095/С-best-practice-решение-для-использования-нескольких-b
ackgroundservice-объектов
. https://www.youtube.com/watch?v=CEr3GcE3YJc
. https://t.me/s/NetDeveloperDiary?before=1259
. https://www.reddit.com/r/dotnet/comments/ixja8w/use_systemiopipelines_and_systemthreadingchannels/
. https://habr.com/ru/companies/microsoft/articles/423105/
. https://learn.microsoft.com/ru-ru/dotnet/standard/io/pipe-operations
. https://learn.microsoft.com/ru-ru/dotnet/standard/io/how-to-use-named-pipes-for-network-interprocess-co
mmunication
. https://www.youtube.com/watch?v=1koWtKkKb_o
. https://habr.com/ru/articles/81067/
. https://rsdn.org/forum/dotnet/3730840.hot
. https://www.reddit.com/r/csharp/comments/r0e0t1/named_pipes_in_net_6_with_tray_icon_and_service/
. https://iro23.ru/sites/default/files/mark_lutc._programmirovanie_na_python.pdf
. https://pyatilistnik.org/roles-and-components-windows-server/
. https://learn.microsoft.com/ru-ru/dotnet/standard/io/pipelines
. https://habr.com/ru/companies/microsoft/articles/423105/
. https://learn.microsoft.com/ru-ru/dotnet/api/system.io.pipes?view=net-10.0
. https://www.reddit.com/r/dotnet/comments/1grwc4u/is_systemiopipelines_still_a_thing/
. https://anthonysimmon.com/local-ipc-over-named-pipes-aspnet-core-streamjsonrpc-dotnet/
. https://devblogs.microsoft.com/dotnet/system-io-pipelines-high-performance-io-in-net/
. https://citforum.ru/operating_systems/nwclient/ch19.shtml
. https://stackoverflow.com/questions/77336961/cannot-connect-to-sql-server-using-named-pipes-through-n
et-application
. https://learn.microsoft.com/ru-ru/dotnet/standard/io/how-to-use-named-pipes-for-network-interprocess-co
mmunication
. https://learn.microsoft.com/ru-ru/dotnet/api/system.io.pipes.namedpipeserverstream?view=net-8.0
. https://citforum.ru/operating_systems/nwclient/ch19.shtml
. https://learn.microsoft.com/ru-ru/dotnet/api/system.io.pipes.namedpipeserverstream.runasclient?view=net-
8.0
. https://habr.com/ru/articles/189086/
. https://github.com/NewYaroslav/simple-named-pipe-server
. https://stackoverflow.com/questions/36457127/named-pipes-for-client-server-implementation-how-will-serv
er-distinguish-between
. https://www.cyberforum.ru/csharp-beginners/thread674059.html
. http://www.silicontaiga.ru/home.asp?artId=5747
. https://learn.microsoft.com/ru-ru/dotnet/standard/io/how-to-use-named-pipes-for-network-interprocess-co
mmunication
. https://learn.microsoft.com/ru-ru/windows/win32/ipc/named-pipe-instances
. https://codeby.net/threads/trably-s-namedpipes.2938/
. https://www.cyberforum.ru/csharp-net/thread694836.html
. https://citforum.ru/operating_systems/nwclient/ch19.shtml
. https://www.reddit.com/r/csharp/comments/x9eya7/how_to_connect_two_programs_running_on_the_same/
. https://stackoverflow.com/questions/55150937/named-pipe-server-with-multiple-clients-c
. https://habr.com/ru/companies/vsk_insurance/articles/822873/
. https://www.mql5.com/ru/articles/115
. http://www.silicontaiga.ru/home.asp?artId=5747
. https://learn.microsoft.com/ru-ru/windows/win32/ipc/named-pipe-instances
. https://learn.microsoft.com/ru-ru/dotnet/standard/io/how-to-use-named-pipes-for-network-interprocess-co
mmunication
. https://stackoverflow.com/questions/55150937/named-pipe-server-with-multiple-clients-c
. https://www.linux.org.ru/forum/development/15350763
. http://rsdn.org/forum/flame.comp/7054938.hot
. http://www.silicontaiga.ru/home.asp?artId=5747
. https://citforum.ru/operating_systems/nwclient/ch19.shtml
. https://xakep.ru/2025/01/28/named-pipes/
. https://github.com/NewYaroslav/simple-named-pipe-server
. https://habr.com/ru/articles/81067/
. https://azjio.narod.ru/autoit3_docs/libfunctions/namedpipes_management.htm
. https://www.cyberforum.ru/csharp-beginners/thread674059.html
. https://learn.microsoft.com/ru-ru/dotnet/standard/io/how-to-use-named-pipes-for-network-interprocess-co
mmunication
. https://www.youtube.com/watch?v=Yhqzb3qIkwQ
. https://learn.microsoft.com/en-us/dotnet/standard/io/how-to-use-named-pipes-for-network-interprocess-co
mmunication
. https://stackoverflow.com/questions/77034925/c-sharp-inter-process-communication-using-named-pipes-
what-am-i-doing-wrong
. https://anthonysimmon.com/local-ipc-over-named-pipes-aspnet-core-streamjsonrpc-dotnet/
. https://www.codeguru.com/csharp/inter-process-communication-in-net-using-named-pipes-part-1/
. https://softwareparticles.com/interprocess-communication-named-pipes/
. https://github.com/yuramag/NamedPipesInteropDemo
. https://dev.to/gabbersepp/ipc-between-c-and-c-by-using-named-pipes-4em9
. https://www.reddit.com/r/csharp/comments/x9eya7/how_to_connect_two_programs_running_on_the_same/
. https://www.reddit.com/r/csharp/comments/etn8mw/best_way_of_doing_ipc_on_windows_with_net_these/
. https://www.cyberforum.ru/csharp-net/thread2321956.html
. https://www.frolov-lib.ru/books/bsp/v27/ch2_3.htm
. http://karlson86.blogspot.com/2010/02/named-pipes-c-vb.html
. https://ru.stackoverflow.com/questions/467521/Взаимодействие-процессов-c
. https://forum.ixbt.com/topic.cgi?id=21%3A116
. https://habr.com/ru/articles/122108/
. https://learn.microsoft.com/ru-ru/dotnet/api/system.io.pipes.namedpipeserverstream?view=net-8.0
. https://learn.microsoft.com/ru-ru/dotnet/standard/io/how-to-use-named-pipes-for-network-interprocess-co
mmunication
. https://learn.microsoft.com/ru-ru/dotnet/core/extensions/scoped-service
. https://learn.microsoft.com/ru-ru/dotnet/api/system.io.pipes.namedpipeclientstream?view=net-8.0
. https://learn.microsoft.com/ru-ru/dotnet/architecture/microservices/multi-container-microservice-net-applic
ations/background-tasks-with-ihostedservice
. https://learn.microsoft.com/ru-ru/dotnet/core/extensions/queue-service
. https://www.youtube.com/watch?v=GB4oAcja55w
. https://habr.com/ru/articles/664962/
. https://habr.com/ru/companies/chibbis/articles/871588/
. https://aspireify.net/a/240628/using-masstransit-with-.net-aspire
. https://fiyaz-hasan-me-blog.azurewebsites.net/aspire-messaging-with-rabbitmq-and-masstransit/
. https://github.com/dotnet/aspire-samples/issues/94
. https://skillstaff.ru/catalog-specialists/activity_area-it/key_skills-google-directions-api/
. https://habr.com/ru/articles/758938/
. https://www.youtube.com/watch?v=GB4oAcja55w
. https://habr.com/ru/articles/81067/
. https://fiyaz-hasan-me-blog.azurewebsites.net/aspire-messaging-with-rabbitmq-and-masstransit/
. https://github.com/MassTransit/MassTransit/discussions/4780
. https://stackoverflow.com/questions/34495092/interprocess-message-broadcast
. https://www.reddit.com/r/dotnet/comments/1ltvw2i/net_aspire_asb_emulator_with_masstransit_stuck/
. https://www.codeproject.com/articles/Inter-Process-Communication-in-NET-Using-Named-Pip
. https://aspireify.net/a/240628/using-masstransit-with-.net-aspire
. https://github.com/MassTransit/Sample-Aspire
Комментариев нет:
Отправить комментарий