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

时间:2011-11-08 15:31:25

标签: c# .net asynchronous stream

我有TCP服务器,什么接收大数据不间断。 我需要向许多客户广播此流。

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

3 个答案:

答案 0 :(得分:2)

如果您想异步执行此操作,则可以利用System.Threading.Tasks namespace

首先,您需要StreamTask个实例的地图,可以等待完成:

IDictionary<Stream, Task> streamToTaskMap = outputStreams.
    ToDictionary(s => s, Task.Factory.StartNew(() => { });

上面有一点点开销,因为有一个浪费的Task实例什么都不做,但考虑到你需要执行的Task个实例和延续的数量,这个价格很小。

从那里,您将从流中读取内容,然后异步地将其写入每个Stream实例:

byte[] buffer = new byte[<buffer size>];
int read = 0;

while ((read = inputStream.Read(buffer, 0, buffer.Length)) > 0)
{
    // The buffer to copy into.
    byte[] copy = new byte[read];

    // Perform the copy.
    Array.Copy(buffer, copy, read);

    // Cycle through the map, and replace the task with a continuation
    // on the task.
    foreach (Stream stream in streamToTaskMap.Keys)
    {
        // Continue.
        streaToTaskMap[stream] = streaToTaskMap[stream].ContinueWith(t => {
            // Write the bytes from the copy.
            stream.Write(copy, 0, copy.Length);
        });
    }
}

最后,您可以通过调用

等待写入的所有流
Task.WaitAll(streamToTaskMap.Values.ToArray());

有几点需要注意。

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

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

此外,能够在Stream类上使用BeginWrite / EndWrite方法更为理想;因为没有ContinueWithAsync方法将采用Task并继续使用异步方法,所以调用异步版本的读取没有任何好处。

这是其中一种情况,可能最好自己调用BeginWrite / EndWrite(以及BeginRead / EndRead),以便充分利用异步操作;当然,这会有点复杂,因为你不会对Task提供的操作结果进行封装,如果你使用匿名的话,你必须对buffer采取相同的预防措施。方法/闭包。

答案 1 :(得分:1)

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

的流
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 chunk:

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

答案 2 :(得分:0)

基本上,您想要线程化您的应用程序。这是一个线程和TCP / IP

的简单示例

C# Tutorial - Simple Threaded TCP Server | Switch on the Code