等待流的人口

rab*_*ana 6 c# resharper asynchronous stream async-await

在我的MVC控制器中,我有一个动作将填充我稍后将使用的流:

[HttpPost]
public async Task<HttpResponseMessage> BuildFileContent(FileParameters fileParams)
{
    byte[] output;
    if (fileParams != null)
    {
        using (var stream = new MemoryStream())
        {
            await Task.Run(() => PopulateFile(fileParams, stream)); // Here i populate the stream
            stream.Flush();
            output = stream.ToArray();
        }
        var guid = Guid.NewGuid().ToString();
        FileContents.Add(guid, output); // just save the content for later use
        return this.Request.CreateResponse(HttpStatusCode.OK, new { Value = guid });
    }

    return this.Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Invalid parameters");
}
Run Code Online (Sandbox Code Playgroud)

我有这个问题,因为ReSharper正在发出警告:access on disposed closure在线上PopulateFile(fileParams, stream)指出stream.

我已经搜索了它的含义,它似乎警告我可以使用已经处理好的流.

我想等待流的人口,因为任务可能需要很长时间.

有没有办法可以在没有ReSharper发出此警告的情况下等待流的填充?而且,我streamusing子句内部调用,直到我调用flush或者using子句的最后一行被执行时才应该处理流?那么为什么ReSharper警告要访问一个被处理的流?

i3a*_*non 5

Resharper警告你,因为你正在使用lambda表达式中的流,该表达式基本上可以在using范围内运行,而不仅仅是在范围内运行.
如果这是你的代码,你可以在任务结束之前处理流,你就可以拥有一个ObjectDisposedException:

Task task = null;
using (var stream = new MemoryStream())
{
   task = Task.Run(() => PopulateFile(fileParams, stream)); // Here i populate the stream
   stream.Flush();
   output = stream.ToArray();
}
await task;
Run Code Online (Sandbox Code Playgroud)

但是await,在您的情况下,您只需在该操作完成后进行该操作并处理流.所以基本上你是清楚的,但Resharper显然不知道.

要完全清除警告,您可以将using范围放在任务中:

await Task.Run(() => 
{
     using (var stream = new MemoryStream())
     {
         PopulateFile(fileParams, stream);
         stream.Flush();
         output = stream.ToArray();
     }
});
Run Code Online (Sandbox Code Playgroud)

我建议你这样做.