gpt4 book ai didi

c# - 使用 async/await 和 System.Threading.Tasks.Parallel 时出现奇怪的执行跳转

转载 作者:行者123 更新时间:2023-12-03 00:10:10 25 4
gpt4 key购买 nike

我有以下方法:

public async Task ExecuteAsync()
{
Task<IEnumerable<Comment>> gettingComments = RetrieveComments();

Dictionary<string, ReviewManager> reviewers = ConfigurationFacade.Repositories.ToDictionary(name => name, name => new ReviewManager(name));

IEnumerable<Comment> comments = await gettingComments;

Parallel.ForEach(reviewers, (reviewer) => {
Dictionary<Comment, RevisionResult> reviews = reviewer.Value.Review(comments);

int amountModerated = ModerateComments(reviews.Where(r => r.Value.IsInsult), "hide");
});
}

我的ModerateComments方法如下所示:

private Task<int> ModerateComments(IEnumerable<Comment> comments, string operation)
{
return Task.Factory.StartNew(() =>
{
int moderationCount = 0;
Parallel.ForEach(comments, async (comment) =>
{
bool moderated = await ModerateComment(comment, operation); //Problem here
if(moderated)
moderationCount++;
}
return moderationCount;
};
}

最后:

private async Task<bool> ModerateComment(Comment comment, string operation, string authenticationToken = null)
{
if(comment == null) return false;

if(String.IsNullOrWhiteSpace(authenticationToken))
authenticationToken = CreateUserToken(TimeSpan.FromMinutes(1));

string moderationEndpoint = ConfigurationFacade.ModerationEndpoint;

using(HttpRequestMessage request = new HttpRequestMessage())
{
request.Method = HttpMethod.Post;
request.RequestUri = new Uri(moderationEndpoint);
using(HttpResponseMessage response = await _httpClient.SendAsync(request)) //Problem here
{
if(!response.IsSuccessStatusCode)
{
if(response.StatusCode == HttpStatusCode.Unauthorized)
return await ModerateComment(comment, operation, null); //Retry operation with a new access token
else if(response.StatusCode == HttpStatusCode.GatewayTimeout)
return await ModerateComment(comment, operation, authenticationToken); //Retry operation

return false;
}
}
}

return true;
}

我在运行时遇到一个奇怪的问题。上面的所有代码都工作正常,除了到达以下行时:

using(HttpResponseMessage response = await _httpClient.SendAsync(request)) {
//...
}

当我调试我的应用程序时,会执行该指令,但在此之后,它不会抛出任何异常,也不会返回任何内容,它只是完成执行,并且我派生到 Parallel.ForEach 上的下一条语句。循环。

这真的很难解释,所以我会发布一些图片:

到目前为止一切都很好,我到达了以下代码行: Image01

执行进展顺利,我到达了对审核 API 的调用 Image02

即使我在调试器中按 F10(Next 语句),执行流程也会跳转到 Parallel.ForEach 循环中的下一个循环。

Image03

正如你所看到的,我在 try-catch 中有断点,以防万一抛出任何异常,但断点永远不会被激活,if(moderacion) commentCount++ 中的断点也不会被激活。 .

那么这里会发生什么?我的执行流程到哪里去了?将 POST 请求发送到 API 后,它就会消失。

继续执行后,可枚举中的所有元素都会进行相同的跳转,因此,我的 commentCount变量最终等于 0 Image04

最佳答案

您不需要 Parallel.ForEachTask.Factory.StartNew 来执行 IO 绑定(bind)工作:

private async Task<int> ModerateCommentsAsync(IEnumerable<Comment> comments, string operation)
{
var commentTasks = comments.Select(comment => ModerateCommentAsync(comment, operation));

await Task.WhenAll(commentTasks);
return commentTasks.Count(x => x.Result);
}

常见做法是将 Async 后缀添加到异步方法。

关于c# - 使用 async/await 和 System.Threading.Tasks.Parallel 时出现奇怪的执行跳转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31124010/

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