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" />
<PackageReference Include="MessageStream" />
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
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#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
#tool nuget:?package=MessageStream&version=1.2.1
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
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 | Versions 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.