MessageStream 1.2.1

dotnet add package MessageStream --version 1.2.1
                    
NuGet\Install-Package MessageStream -Version 1.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="MessageStream" Version="1.2.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="MessageStream" Version="1.2.1" />
                    
Directory.Packages.props
<PackageReference Include="MessageStream" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add MessageStream --version 1.2.1
                    
#r "nuget: MessageStream, 1.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.
#:package MessageStream@1.2.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=MessageStream&version=1.2.1
                    
Install as a Cake Addin
#tool nuget:?package=MessageStream&version=1.2.1
                    
Install as a Cake Tool

MessageStream Library

C# Channel 기반의 간단하고 강력한 스레드 간 데이터 통신 라이브러리입니다.

🎯 기본 사용법

1. 기본 읽기/쓰기

using Threading.Messaging;

// Producer 스레드
var producer = Task.Run(async () =>
{
    using var hub = MessageStream.Open("channel1");
    await hub.WriteAsync<string>("Hello World!");
    await hub.WriteAsync<int>(42);
});

// Consumer 스레드
var consumer = Task.Run(async () =>
{
    using var hub = MessageStream.Open("channel1");
    var message = await hub.ReadAsync<string>();
    var number = await hub.ReadAsync<int>();
    
    Console.WriteLine($"Message: {message}, Number: {number}");
});

await Task.WhenAll(producer, consumer);

2. 타임아웃 설정

// 2초 타임아웃 설정
using var hub = MessageStream.Open("channel1", timeout: 2000);

try
{
    await hub.WriteAsync<string>("Data");
    var result = await hub.ReadAsync<string>();
}
catch (TimeoutException ex)
{
    Console.WriteLine($"작업 시간 초과: {ex.Message}");
}

3. Non-blocking 읽기

using var hub = MessageStream.Open("channel1");

// 즉시 읽기 시도 (블로킹 없음)
if (hub.TryRead<string>(out var result))
{
    Console.WriteLine($"읽은 데이터: {result}");
}
else
{
    Console.WriteLine("읽을 수 있는 데이터가 없습니다.");
}

🏗️ 고급 사용법

1. 여러 스레드에서 동일 채널 공유

// 여러 Producer
var producers = Enumerable.Range(0, 3).Select(i => 
    Task.Run(async () =>
    {
        using var hub = MessageStream.Open("shared-channel");
        await hub.WriteAsync<int>(i);
        Console.WriteLine($"Producer {i} 완료");
    })
).ToArray();

// 단일 Consumer
var consumer = Task.Run(async () =>
{
    using var hub = MessageStream.Open("shared-channel");
    for (int i = 0; i < 3; i++)
    {
        var value = await hub.ReadAsync<int>();
        Console.WriteLine($"받은 값: {value}");
    }
});

await Task.WhenAll(producers.Concat(new[] { consumer }));

2. 순차적 채널 사용

// 첫 번째 사용
using (var hub1 = MessageStream.Open("sequential"))
{
    await hub1.WriteAsync<string>("First message");
}

// 두 번째 사용 (같은 채널)
using (var hub2 = MessageStream.Open("sequential"))
{
    await hub2.WriteAsync<string>("Second message");
}

// 읽기 (같은 채널)
using (var hub3 = MessageStream.Open("sequential"))
{
    var msg1 = await hub3.ReadAsync<string>();
    var msg2 = await hub3.ReadAsync<string>();
    Console.WriteLine($"Messages: {msg1}, {msg2}");
}

3. TryPeek을 이용한 데이터 처리 흐름

var stream = MessageStream.Open("test");
await stream.WriteAsync("첫번째");
await stream.WriteAsync("두번째");
await stream.WriteAsync("세번째");

// TryPeek - 데이터를 제거하지 않고 확인만
if (stream.TryPeek<string>(out var peeked))
{
    Console.WriteLine($"다음 메시지: {peeked}"); // "첫번째" 출력
}

// 다시 Peek 해도 같은 데이터
if (stream.TryPeek<string>(out var peeked2))
{
    Console.WriteLine($"여전히: {peeked2}"); // 또다시 "첫번째" 출력
}
// 실제로 읽어야 데이터가 제거됨
var actual = await stream.ReadAsync<string>(); // "첫번째" 반환하고 제거

// 이제 Peek하면 다음 데이터가 보임
if (stream.TryPeek<string>(out var peeked3))
{
    Console.WriteLine($"이제 다음: {peeked3}"); // "두번째" 출력
}

🛡️ 예외 처리

using var hub = MessageStream.Open("error-channel", timeout: 1000);

try
{
    await hub.WriteAsync<string>("test");
    var result = await hub.ReadAsync<int>(); // 타입 불일치
}
catch (TimeoutException)
{
    Console.WriteLine("작업 시간 초과");
}
catch (InvalidCastException)
{
    Console.WriteLine("타입 캐스팅 실패");
}
catch (ObjectDisposedException)
{
    Console.WriteLine("이미 해제된 MessageStream 사용");
}
catch (InvalidOperationException)
{
    Console.WriteLine("채널이 완료됨");
}

📋 API 레퍼런스

MessageStream 클래스

메서드 설명
Open(string name, int timeout = 5000) 지정된 이름의 채널을 열거나 기존 채널에 연결
WaitToReadAsync(CancellationToken cancellationToken = default) 채널에서 읽기 작업이 가능할때 까지 대기
WriteAsync<T>(T data, CancellationToken cancellationToken = default) 채널에 데이터를 비동기적으로 쓰기
ReadAsync<T>(CancellationToken cancellationToken = default) 채널에서 데이터를 비동기적으로 읽기
TryRead<T>(out T result) 즉시 읽기 시도 (블로킹 없음)
TryPeek<T>(out T result) 채널에서 데이터를 확인 (데이터를 제거하지 않음)
Close(string name) 특정 채널 닫기
CloseAll() 모든 채널 닫기
Exists(string name) 채널 존재 여부 확인

예외 타입

예외 발생 조건
TimeoutException 읽기/쓰기 작업이 시간 초과된 경우
InvalidCastException 데이터 타입 캐스팅 실패
ObjectDisposedException 해제된 MessageStream 사용
InvalidOperationException 완료된 채널에서 읽기/쓰기 시도
ArgumentNullException null 매개변수 전달
ArgumentException 잘못된 매개변수 전달

💡 모범 사례

✅ 권장사항

// 1. using 문 사용
using var hub = MessageStream.Open("channel1");

// 2. 타임아웃 설정
using var hub = MessageStream.Open("channel1", timeout: 2000);

// 3. 예외 처리
try
{
    var cts = new CancellationTokenSource();
    var data = await hub.ReadAsync<string>(cts.Token);
}
catch (TimeoutException)
{
    // 타임아웃 처리
}

❌ 피해야 할 사항

// 1. using 없이 사용 (메모리 누수 위험)
var hub = MessageStream.Open("channel1"); // ❌

// 2. 타입 불일치
await hub.WriteAsync<string>("hello");
var number = await hub.ReadAsync<int>(); // ❌ InvalidCastException

// 3. 너무 짧은 타임아웃
using var hub = MessageStream.Open("channel1", timeout: 1); // ❌

🚨 주의사항

  • 채널 공유: 같은 이름의 채널은 모든 스레드에서 공유됩니다.
  • 타입 안전성: 쓰기와 읽기 시 타입이 일치해야 합니다.
  • 순서 보장: 데이터는 FIFO(First In, First Out) 순서로 처리됩니다.
  • 메모리 관리: using 문을 사용하여 자동 리소스 해제를 권장합니다.
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 is compatible.  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.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net6.0

    • No dependencies.
  • net7.0

    • No dependencies.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.1 125 7/16/2025
1.2.0 122 7/16/2025
1.1.0 117 7/14/2025
1.0.0 120 7/14/2025