如何将流复制到多个流异步C#.NET

如何将流复制到多个流异步C#.NET,c#,.net,asynchronous,stream,C#,.net,Asynchronous,Stream,我有TCP服务器,可以不间断地接收大数据。 我需要向许多客户广播这个流 更新: 我需要播放视频流。也许有现成的解决方案?产生一个线程,将流以及要写入的流传递给它 byte[] buffer = new byte[BUFFER_SIZE]; int btsRead = 0; while ((btsRead = inputStream.Read(buffer, 0, BUFFER_SIZE)) > 0) { foreach (Stream oStream in outputStrea

我有TCP服务器,可以不间断地接收大数据。 我需要向许多客户广播这个流

更新:
我需要播放视频流。也许有现成的解决方案?

产生一个线程,将流以及要写入的流传递给它

byte[] buffer = new byte[BUFFER_SIZE];
int btsRead = 0;

while ((btsRead = inputStream.Read(buffer, 0, BUFFER_SIZE)) > 0)
{
    foreach (Stream oStream in outputStreams)
        oStream.Write(buffer, 0, btsRead);
}
编辑:要并行写入,请执行以下操作:

将foreach块替换为:

Parallel.ForEach(outputStreams, oStream =>
{
    oStream.Write(buffer, 0, btsRead);
});

基本上,您希望线程化应用程序。下面是一个线程和TCP/IP的简单示例


如果要异步执行此操作,则可以利用

首先,您需要一个实例到可等待完成的实例的映射:

IDictionary<Stream, Task> streamToTaskMap = outputStreams.
    ToDictionary(s => s, Task.Factory.StartNew(() => { });
最后,您可以通过调用来等待写入的所有流:

Task.WaitAll(streamToTaskMap.Values.ToArray());
有几件事需要注意

首先,由于传递给的lambda,需要
缓冲区的副本
;lambda是一个封装
缓冲区的闭包,因为它是异步处理的,所以内容可能会更改。每个连续性都需要自己的缓冲区副本来读取

这也是调用使用属性的原因;否则,必须在循环的每次迭代中复制
read
变量

此外,能够利用
类上的/方法更为理想;由于没有
ContinueWithAsync
方法将执行
任务
并继续使用异步方法,因此调用异步版本的read没有任何好处


在这种情况下,最好自己调用BeginWrite/EndWrite(以及/),以便充分利用异步操作;当然,这会有点复杂,因为您没有
Task
提供的对操作结果的封装,如果您使用匿名方法/闭包,您将必须对
缓冲区采取相同的预防措施。

请提供有关您尝试的代码以及哪些代码有效/无效的更多详细信息。是否有必要使用TCP进行广播?您的要求通常是通过UDP实现的…我试图广播的数据是stream。如果我可以从silverlight应用程序连接到UPD,“foreach”则不需要TCP?这是个好办法吗?如果我有1000个客户呢?foreach和for循环一样。我刚才介绍的代码应该在服务器接收上传流时生成的后台线程中运行。您可以尝试其他技术,例如对客户机流进行异步写入,以进一步分摊成本,但我介绍的是一个相对简单的解决方案,应该可以工作。
Task.WaitAll(streamToTaskMap.Values.ToArray());