Пример асинхронной передачи данных через потоки данных
Можете показать пример, как написать 2 асинхронные задачи, чтобы они использовали один и тот же Stream (одна пишет, другая читает)? Ну и еще я хочу иметь возможность закинуть их в одну коллекцию и вызвать через Task.WhenAll(). При этом нужно чтобы записывающая таска не писала все данные разом, а отсылала их кусками. Пример:
private static async Task Write(Stream stream)
{
var writer = new StreamWriter(stream);
await writer.WriteAsync("aba");
await Task.Delay(1000);
await writer.WriteAsync("caba");
}
using var stream = new MemoryStream();
var tasks = new[] { Write(stream), Read(stream) };
await Task.WhenAll(tasks);
Console.WriteLine("Finished");
Результат должен выглядеть, например, чтобы в консоль сначала вывело "aba" (ну или не целиком, пусть это определяется размером буфера) и спустя секунду - оставшаяся часть строки
Как должен выглядеть метод Read? Или я использую нежизнеспособный подход и задача об асинхронном использовании стрима решается как-то иначе?
Естественно, выгружать условную строку в оперативную память целиком - не вариант, я использую стримы как раз для того чтобы обрабатывать переданные данные динамически
Ответы (1 шт):
Судя по задаче, вы выбрали неверный инструмент. Для того что вам нужно, используется другой класс - Channel.
static async Task Main(string[] args)
{
Channel<string> channel = Channel.CreateUnbounded<string>();
await Task.WhenAll(ReadAsync(channel.Reader), WriteAsync(channel.Writer));
}
static async Task ReadAsync(ChannelReader<string> reader)
{
await foreach (string text in reader.ReadAllAsync())
{
Console.Write(text);
}
}
static async Task WriteAsync(ChannelWriter<string> writer)
{
await writer.WriteAsync("aba");
await Task.Delay(1000);
await writer.WriteAsync("caba");
writer.Complete(); // сообщает каналу, что данных больше нет, чтобы Reader завершился
}