1
流在我目前的代码,我有一个这样的方法来从设备读出的数据(伪代码):返回流立即然后写异步
public async Task<string> ReadAllDataFromDevice()
{
var buffer = "";
using (var device = new Device())
{
while(device.HasMoreData)
{
buffer += await device.ReadLineAsync();
}
}
return buffer;
}
然后我想通过发送所有数据网络到一些接收器。数据量可能非常大。所以很显然,上述设计不是非常有效的内存,因为它需要读取所有数据,然后才能开始将其发送到网络套接字。
所以我想要的是一个返回流的函数。事情是这样的:
public async Task<Stream> ReadAllDataFromDevice()
{
var stream = new MemoryStream();
using (var device = new Device())
using (var streamWriter = new StreamWriter(stream, new UTF8Encoding(), 512, true))
{
while(device.HasMoreData)
{
var line = await device.ReadLineAsync();
await streamWriter.WriteLineAsync(line);
}
await streamWriter.FlushAsync();
}
return stream;
}
这将返回一个流,但它显然并没有解决我的问题,因为只有在所有的数据已经从设备读取返回流。
于是我想出了这一点:
public Stream ReadAllDataFromDevice()
{
var stream = new MemoryStream();
Task.Run(async() => {
using (var device = new Device())
using (var streamWriter = new StreamWriter(stream, new UTF8Encoding(), 512, true))
{
while(device.HasMoreData)
{
var line = await device.ReadLineAsync();
await streamWriter.WriteLineAsync(line);
}
await streamWriter.FlushAsync();
}
});
return stream;
}
这是一个好的设计?我特别关心线程安全性,lambda中使用的流对象的生命周期以及异常处理。
或者是否有这种问题更好的模式?
编辑
其实我只是想出了另一种设计,看起来干净多了我。相反,具有ReadAllDataFromDevice()
函数返回一个流,我让数据的消费者提供流,就像这样:
public async Task ReadAllDataFromDevice(Stream stream)
{
using (var device = new Device())
using (var streamWriter = new StreamWriter(stream, new UTF8Encoding(), 512, true))
{
while(device.HasMoreData)
{
var line = await device.ReadLineAsync();
await streamWriter.WriteLineAsync(line);
}
await streamWriter.FlushAsync();
}
}
你怎么知道什么时候有没有被接收的数据量?这条线没有意义:device.HasMoreData。 – jdweng