使用System.Threading.Tasks.Task <stream>而不是Stream </stream>

时间:2011-12-06 12:38:21

标签: c# asynchronous wcf-web-api

我在之前版本的WCF Web API上使用了类似下面的方法:

// grab the posted stream
Stream stream = request.Content.ContentReadStream;

// write it to   
using (FileStream fileStream = File.Create(fullFileName, (int)stream.Length)) {

    byte[] bytesInStream = new byte[stream.Length];
    stream.Read(bytesInStream, 0, (int)bytesInStream.Length);
    fileStream.Write(bytesInStream, 0, bytesInStream.Length);
}

但是在预览6中,HttpRequestMessage.Content.ContentReadStream属性消失了。我相信它现在看起来应该像这样:

// grab the posted stream
System.Threading.Tasks.Task<Stream> stream = request.Content.ReadAsStreamAsync();

但是我无法弄清楚using语句中其余代码应该是什么样的。任何人都可以为我提供一种方法吗?

3 个答案:

答案 0 :(得分:9)

您可能需要根据之前/之后发生的代码进行调整,并且没有错误处理,但是这样的话:

Task task = request.Content.ReadAsStreamAsync().ContinueWith(t =>
{
    var stream = t.Result;
    using (FileStream fileStream = File.Create(fullFileName, (int) stream.Length)) 
    {
        byte[] bytesInStream = new byte[stream.Length];
        stream.Read(bytesInStream, 0, (int) bytesInStream.Length);
        fileStream.Write(bytesInStream, 0, bytesInStream.Length);
    }
});

如果您的代码稍后需要确保已完成此操作,则可以调用task.Wait()并阻止此操作完成(或抛出异常)。

我强烈推荐Stephen Toub的Patterns of Parallel Programming加快.NET 4中一些新的异步模式(任务,数据并行等)的速度。

答案 1 :(得分:7)

快速而肮脏的修复:

// grab the posted stream
Task<Stream> streamTask = request.Content.ReadAsStreamAsync();
Stream stream = streamTask.Result; //blocks until Task is completed

请注意,已从API中删除同步版本这一事实表明您应该尝试学习新的异步范例,以避免在高负载下吞噬多个线程。

你可以举例:

streamTask.ContinueWith( _ => {
    var stream = streamTask.Result; //result already available, so no blocking
    //work with stream here
} )

或使用新的异步等待功能:

//async wait until task is complete
var stream = await request.Content.ReadAsStreamAsync(); 

花时间学习异步/等待。它非常方便。

答案 2 :(得分:1)

以下是使用asyncawait

更好地完成此操作的方法
    private async void WhatEverMethod()
    {
        var stream = await response.Content.ReadAsStreamAsync();

        using (FileStream fileStream = File.Create(fullFileName, (int)stream.Length))
        {
            byte[] bytesInStream = new byte[stream.Length];
            stream.Read(bytesInStream, 0, (int)bytesInStream.Length);
            fileStream.Write(bytesInStream, 0, bytesInStream.Length);
        }
    });