2014-05-23 37 views
1

我試圖將傳入的HTTP流複製到另一個流並使用它。如何重定向Request.Content流

當我直接使用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; 
    } 
+0

你習慣開始異步操作,然後等待它們。這是沒有意義的。 – usr

+0

@us當然,但如果我不等,代碼會立即退出,並且不會收到任何數據。這是真正的問題。 – user3077725

+0

然後,我不清楚你想要什麼。你有兩個選擇:立即返回,完成後返回。你還想要什麼? – usr

回答

2

也許,你從錯誤的一面解決問題。 CopyToAsync給你一個完成流的副本,返回的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

我需要做的是在正在寫入時使用recordingSession.AudioStream,但現在我明白從正在寫入的流中讀取數據是不可能的。 – user3077725

0

我想你的意思是這樣的:

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

異步方法返回任務。非異步方法很少會返回任務。

+0

謝謝,但這並不能解決問題。它要麼阻塞,直到所有的數據流,否則它會立即返回,如果我刪除第二個等待。 – user3077725

+0

對,這是因爲你的調用方法應該等待完成對GetAudioStream()的調用。 –

+0

我正在等待GetAudioStream(),但它仍然立即返回。 – user3077725