将方法转换为异步

时间:2017-11-06 18:30:21

标签: c# asynchronous

在尝试使用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...
    }
}

我们最近移动了ThisMethodThrowsExecuteAndIgnoreFileInUseException以使用异步模式,因为之前他们只是在异步客户端方法上使用.Wait(),但现在我们看到的似乎是与文件和处置的竞争条件和所有这些。我现在最好的猜测是lambda函数非常快地返回Task this.client.UploadFile,然后在实际完成工作之前流处理。我们是否需要使lambda异步并等待其中的调用以避免此问题? “async-ify”这段代码的正确方法是什么?

0 个答案:

没有答案