在尝试使用System.ObjectDisposedException
作为文件类型发出POST请求时,我偶尔会看到StreamContent
。我上周看过一两次,但无法复制,但队友一直在打这个错误。这是有问题的代码。我已经简化了一点,但确保保持与我们的代码相同的结构:
async Task ThisMethodThrows()
{
string filePath = "foo.file";
await ExecuteAndIgnoreFileInUseException(() =>
{
using (FileStream filestream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
return this.client.UploadFile(filestream);
}
});
}
// We have to do this a lot, so there's a common method to avoid needing to copy this bulky try-catch and HResult everywhere
static async Task ExecuteAndIgnoreFileInUseException(Func<Task> func)
{
try
{
await func();
}
catch (Exception)
{
if (ex.HResult != -2146233088) // This HResult indicates file is in use
{
throw;
}
}
}
// Code in this.client from above:
private readonly HttpClient inner;
public Client()
{
this.inner = new HttpClient();
// other misc setup...
}
async Task UploadFile(Stream stream)
{
using (HttpRequestMessage message = new HttpRequestMessage())
{
message.Method = HttpMethod.Post;
message.Content = new StreamContent(stream);
message.RequestUri = new Uri("http://foo.com/bar");
HttpResponseMessage response = await this.inner.SendAsync(message);
// error handling...
}
}
我们最近移动了ThisMethodThrows
和ExecuteAndIgnoreFileInUseException
以使用异步模式,因为之前他们只是在异步客户端方法上使用.Wait()
,但现在我们看到的似乎是与文件和处置的竞争条件和所有这些。我现在最好的猜测是lambda函数非常快地返回Task
this.client.UploadFile
,然后在实际完成工作之前流处理。我们是否需要使lambda异步并等待其中的调用以避免此问题? “async-ify”这段代码的正确方法是什么?