【发布时间】:2015-06-29 19:31:39
【问题描述】:
我有以下方法:
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 循环上的下一条语句。
这真的很难解释,所以我会发布一些图片:
到目前为止一切顺利,我到达了以下代码行:
执行进展顺利,我到达了对 Moderation API 的调用
即使我在调试器中按 F10(下一个语句),执行流程也会跳转到 Parallel.ForEach 循环中的下一个循环。
如你所见,我在 try-catch 中有断点,以防万一抛出任何异常,但断点从未激活,if(moderacion) commentCount++ 中的断点也没有激活。
那么这里会发生什么?我的执行流程去哪儿了?它只是在向 API 发送 POST 请求后消失。
继续执行后,枚举中的所有元素都进行相同的跳转,因此,我的commentCount变量最终等于0
【问题讨论】:
标签: c# .net multithreading asynchronous async-await