使用HttpClient发送两个相隔2秒的POST请求

时间:2013-11-06 01:57:12

标签: c# async-await

我正在尝试为DelegatingHandler编写一个集成测试,以防止重复请求。处理程序检查数据库以查看请求是否已被处理,如果在前一个请求仍在运行时发出重复请求,则返回407-Conflict。

我的测试中有以下代码:

HttpClient client = new HttpClient();
var responseTask1 = client.PostAsJsonAsync(RequestUriWithDuplicatePrevention, ReadRequestContent("DuplicateRequestJsonContent.json"));
var responseTask2 = client.PostAsJsonAsync(RequestUriWithDuplicatePrevention, ReadRequestContent("DuplicateRequestJsonContent.json"));

var response1 = responseTask1.Result;
var response2 = responseTask2.Result;

两个请求都在同一时间登录到数据库。如何在一段时间内延迟第二次请求?

我尝试过添加一个Thread.Sleep(500),但似乎没有什么区别。

修订代码

此代码似乎在大多数时间都有效,但它不是100%可靠。

        [TestMethod]
    public void ShouldReturn407ConflictWhenDuplicateRequestSubmitted()
    {
        var results = ExecutePostRequests().Result;

        Assert.AreEqual(HttpStatusCode.OK, results[0].StatusCode);
        Assert.AreEqual(HttpStatusCode.Conflict, results[1].StatusCode);
    }

    private async Task<HttpResponseMessage[]> ExecutePostRequests()
    {
        HttpClient client = new HttpClient();

        var task1 = ExecutePost(client, 0);
        var task2 = ExecutePost(client, 4000);

        var response1 = await task1;
        var response2 = await task2;

        return new[] {response1, response2};
    }

    private async Task<HttpResponseMessage> ExecutePost(HttpClient client, int delay)
    {
        await Task.Delay(delay);
        return await client.PostAsync(RequestUriWithDuplicatePrevention,
            ReadRequestContent("DuplicateRequestJsonContent.json"));
    }

正在执行的Web服务有一个Thread.Sleep(5000)。

1 个答案:

答案 0 :(得分:2)

原始代码中的具体问题是,当您在启动异步操作之间应该在之间休眠时,它正在等待获取结果

可以这样纠正:

var responseTask1 = client.PostAsJsonAsync(...);
Thread.Sleep(2000);
var responseTask2 = client.PostAsJsonAsync(...);

var response1 = responseTask1.Result;
var response2 = responseTask2.Result;

您修改后的代码不会遇到此问题,应该可以使用。虽然,我会改变这个:

    var response1 = await task1;
    var response2 = await task2;

    return new[] {response1, response2};

更高效:

    return await Task.WhenAll(task1, task2);