gpt4 book ai didi

c# - 为什么这个异步代码有时会失败,而且只有在没有观察到的情况下才会失败?

转载 作者:太空狗 更新时间:2023-10-30 01:05:20 25 4
gpt4 key购买 nike

这是已经运行了几周的原始代码。在我刚刚进行的测试中,100 次尝试中有 0 次失败。

using (var httpClient = new HttpClient())
{
var tasks = new List<Task>();

tasks.Add(httpClient.GetAsync(new Uri("..."))
.ContinueWith(request =>
{
request.Result.Content.ReadAsAsync<IEnumerable<Foo>>()
.ContinueWith(response =>
{
foos = response.Result;
});
}));

tasks.Add(httpClient.GetAsync(new Uri("..."))
.ContinueWith(request =>
{
request.Result.Content.ReadAsAsync<Bar>()
.ContinueWith(response =>
{
bar = response.Result;
});
}));

await Task.WhenAll(tasks);
}

此代码在 100 次尝试中有 9 次失败,其中一个或两个元组值为 null

var APIresponses = await HttpClientHelper.GetAsync
<
IEnumerable<Foo>,
Bar
>
(
new Uri("..."),
new Uri("...")
);

foos = APIresponses.Item1;
bar = APIresponses.Item2;
private static Task GetAsync<T>(HttpClient httpClient, Uri URI, Action<Task<T>> continuationAction)
{
return httpClient.GetAsync(URI)
.ContinueWith(request =>
{
request.Result.EnsureSuccessStatusCode();

request.Result.Content.ReadAsAsync<T>()
.ContinueWith(continuationAction);
});
}

public static async Task<Tuple<T1, T2>> GetAsync<T1, T2>(Uri URI1, Uri URI2)
{
T1 item1 = default(T1);
T2 item2 = default(T2);

var httpClient = new HttpClient();
var tasks = new List<Task>()
{
GetAsync<T1>(httpClient, URI1, response =>
{
item1 = response.Result;
}),
GetAsync<T2>(httpClient, URI2, response =>
{
item2 = response.Result;
})
};

await Task.WhenAll(tasks);

return Tuple.Create(item1, item2);
}

将代码修改为如下所示,它会在 100 次尝试中再次失败 0 次。

    await Task.WhenAll(tasks);
System.Diagnostics.Debug.WriteLine("tasks complete");
System.Diagnostics.Debug.WriteLine(item1);
System.Diagnostics.Debug.WriteLine(item2);

return Tuple.Create(item1, item2);
}

我已经看了半个多小时了,但我看不出错误在哪里。有人看到了吗?

最佳答案

将评论发给您的 other question ,您很少需要将 async/awaitContinueWith 混合使用。您可以在 async lambda 的帮助下执行“fork”逻辑,例如,问题中的代码可能如下所示:

using (var httpClient = new HttpClient())
{
Func<Task<IEnumerable<Foo>>> doTask1Async = async () =>
{
var request = await httpClient.GetAsync(new Uri("..."));
return response.Content.ReadAsAsync<IEnumerable<Foo>>();
};

Func<Task<IEnumerable<Bar>>> doTask2Async = async () =>
{
var request = await httpClient.GetAsync(new Uri("..."));
return response.Content.ReadAsAsync<IEnumerable<Bar>>();
};

var task1 = doTask1Async();
var task2 = doTask2Async();

await Task.WhenAll(task1, task2);

var result1 = task1.Result;
var result2 = task2.Result;

// ...
}

关于c# - 为什么这个异步代码有时会失败,而且只有在没有观察到的情况下才会失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19175885/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com