等待着溪流的人口



在我的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");
}

我遇到这个问题是因为ReSharper在线路PopulateFile(fileParams, stream)上发出警告:access on disposed closure并指出stream

我已经搜索了它的含义,它似乎警告我可能会使用一个已经处理好的流。

我想等待溪流中的人群,因为这项任务可能需要很长时间。

有没有办法让我在没有ReSharper发出警告的情况下等待溪流的人口?此外,我在using子句中调用stream,在我调用flush或执行using子句的最后一行之前,流不应该被处理,对吗?那么,为什么ReSharper会对访问已处理的流发出警告呢?

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;

但是,在您的情况下,您await该操作并仅在该操作完成后处理流。所以基本上你是清白的,但雷沙珀显然不知道。

要完全清除警告,可以将using作用域放在任务中:

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

我建议你这么做。

@I3arnon的答案是完全正确的,但我想解决一个重要的问题。

我想等待流的填充,因为任务可能需要很长时间。

这是一个崇高的目标,但从await中获益完全取决于您对PopulateFile的实现,根据它的调用方式判断,它可能不是一个异步方法。任何时候你做await Task.Run(() => DoSomethingSynchronously())之类的事情,在释放线程方面都没有任何收获。

我建议仔细研究PopulateFile,确定速度缓慢的原因,看看你是否可以利用任何真正异步的API来进行Web访问、文件I/O等。如果你可以将PopulateFile重写为一个异步方法(即使用async Task PopulateFileAsync(...)这样的签名)来利用这些API,在等待长时间运行的操作时,您将获得真正释放线程的东西,并且您可以直接等待它,而不需要Task.Run:

using (var stream = new MemoryStream())
{
await PopulateFileAsync(fileParams, stream)); // Here i populate the stream
stream.Flush();
output = stream.ToArray();
}

另外,上面的代码不应该引起R#的抱怨。

相关内容

  • 没有找到相关文章

最新更新