使用Async / Await时Stream正在关闭

时间:2014-05-11 02:11:56

标签: c# azure asynchronous asp.net-web-api

我有一点服务可以将blob上传到Azure存储。我试图从WebApi异步操作中使用它,但我的AzureFileStorageService表示流已关闭。

我是async / await的新手,是否有任何好的资源可以帮助我更好地理解它?

WebApi控制器

public class ImageController : ApiController
{
    private IFileStorageService fileStorageService;

    public ImageController(IFileStorageService fileStorageService)
    {
        this.fileStorageService = fileStorageService;
    }

    public async Task<IHttpActionResult> Post()
    {
        if (!Request.Content.IsMimeMultipartContent())
        {
            throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.UnsupportedMediaType));
        }

        await Request.Content.ReadAsMultipartAsync(new MultipartMemoryStreamProvider()).ContinueWith((task) =>
        {

            foreach (var item in task.Result.Contents)
            {
                using (var fileStream = item.ReadAsStreamAsync().Result)
                {
                    fileStorageService.Save(@"large/Sam.jpg", fileStream);
                }

                item.Dispose();
            }

        });

        return Ok();
    }
}

AzureFileStorageService

public class AzureFileStorageService : IFileStorageService
{
    public async void Save(string path, Stream source)
    {
        await CloudStorageAccount.Parse(ConfigurationManager.AppSettings["StorageConnectionString"])
            .CreateCloudBlobClient()
            .GetContainerReference("images")
            .GetBlockBlobReference(path)
            .UploadFromStreamAsync(source); // source throws a stream is disposed exception
    }
}

2 个答案:

答案 0 :(得分:7)

您的Save()方法有问题:您没有返回任务,因此调用方法无法等待它完成。如果你只是想解雇并忘记它,那就好了,但你不能这样做,因为你传入的流将在Save()方法返回后立即处理(感谢{{1声明)。

相反,您将不得不在调用方法中返回usingTask,或者您将不得不在{{1}中拥有文件流阻塞,而是让await方法在完成后处理它。

您可以重写代码的一种方法如下:

(调用方法的片段):

using

保存方法:

Save()

答案 1 :(得分:0)

查看我们几周前发布的AzureBlobUpload示例:

之前的答案肯定是一个很好的解决方案。这只是一个完整的端到端官方样本(也许是其他人开始使用)。

https://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/AzureBlobsFileUploadSample/ReadMe.txt