如何重定向Request.Content流

时间:2014-05-23 22:14:13

标签: c# stream task-parallel-library

我尝试将传入的HTTP流复制到另一个流中,然后使用它。

当我直接使用Request.Content.ReadAsStreamAsync().Result时,一切正常。

我面临的问题是如何"频道"通过另一个原始流。 我编写了流程方法,但问题是它要么阻塞直到所有流数据都到达(当我使用Wait()时),要么它立即返回并且存在而不捕获任何数据。

 private  Task<Stream> GetAudioStream(RecordingSession recordingSession)
    {

        Task<Stream> task = Task<Stream>.Factory.StartNew(() =>
        {
            Request.Content.ReadAsStreamAsync().Result.CopyToAsync(recordingSession.AudioStream).Wait();
            return recordingSession.AudioStream;
        });

        return task;
    }

2 个答案:

答案 0 :(得分:2)

也许,你从错误的一面解决问题。 CopyToAsync为您提供了流的完整副本,Task返回的CopyToAsync在复制完所有数据后就已完成。

如果您不需要整个完整流的副本,或者不想等待所有数据,请手动复制你自己处理每个块:

static async Task<Stream> CopyAndProcessAsync(RecordingSession recordingSession, CancellationToken token)
{
    var srcStream = await Request.Content.ReadAsStreamAsync();

    var dstStream = recordingSession.AudioStream;

    var buffer = new byte[4096];  
    int bytesRead;
    while ((bytesRead = await srcStream.ReadAsync(buffer, 0, buffer.Length, token).ConfigureAwait(false)) != 0)
    {
        await dstStream.WriteAsync(buffer, 0, bytesRead, token).ConfigureAwait(false);

        // do whatever you want with the chunk
        PlaybackChunk(buffer);
    }

    return dstStream;
}

除非您使用GetAudioStream的结果,否则请执行此操作。当您处理完每个块时,可能会发现您根本不需要副本。

答案 1 :(得分:0)

我认为你的意思是这样的:

private async Task<Stream> GetAudioStream(RecordingSession recordingSession)
{
    var result = await Request.Content.ReadAsStreamAsync();
    await result.CopyToAsync(recordingSession.AudioStream);
    return recordingSession.AudioStream;
}

异步方法返回任务。非异步方法很少返回任务。