c# - 从多个线程 C#.Net 调用时 GetWorkItemAsync 方法异常
问题描述
我正在尝试从 VSO 获取工作项的链接,当从单个线程调用时代码似乎工作正常,但在从每个循环的并行调用时抛出异常。
我在类的构造函数中初始化了我的 vso 客户端对象:
vso = new WorkItemReporting(Config.VSTSAccessToken);
然后在一个方法中:
Parallel.ForEach(msrcAbBugsToProcess, new ParallelOptions { MaxDegreeOfParallelism = 10 }, bugId =>
{
var workItemLinks = vso.GetWorkItemSourceCodeLinks(bugId);
});
下面的 witclient 是一个 WorkItemTrackingHttpClient,它位于不同的类 (WorkItemReporting) 中并调用 API。正是这个调用失败了。
public List<string> GetWorkItemSourceCodeLinks(int bugId)
{
var workItemSourceCodeLinks = new List<string>();
var workItem = _witClient.GetWorkItemAsync(bugId, null, null, WorkItemExpand.Relations).Result;
if (workItem?.Relations != null)
{
var validSourceCodeLinkTypes = new List<string> { "ArtifactLink", "Hyperlink" };
foreach (var relation in workItem.Relations)
{
if (validSourceCodeLinkTypes.Contains(relation.Rel))
{
workItemSourceCodeLinks.Add(relation.Url);
}
}
}
}
如果我不使用 Parallel.ForEach 并且我从 API 获取所需的数据,这可以正常工作。当我这样做时,我有 50% 的时间得到这个异常:
Object reference not set to an instance of an object.
at System.Security.Cryptography.X509Certificates.X509CertificateCollection.GetHashCode()
at System.Net.HttpWebRequest.GetConnectionGroupLine()
at System.Net.HttpWebRequest.SubmitRequest(ServicePoint servicePoint)
at System.Net.HttpWebRequest.BeginGetResponse(AsyncCallback callback, Object state)
at System.Net.Http.HttpClientHandler.StartGettingResponse(RequestState state)
at System.Net.Http.HttpClientHandler.StartRequest(Object obj)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at Microsoft.VisualStudio.Services.Common.VssHttpMessageHandler.<SendAsync>d__17.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.Services.Common.VssHttpRetryMessageHandler.<SendAsync>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.<SendAsync>d__48.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.<SendAsync>d__45`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.<SendAsync>d__27`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.<SendAsync>d__26`1.MoveNext()
有什么我做错了吗?
解决方案
一个解决方案是在WorkItemReporting
内部创建Parallel.ForEach
:
Parallel.ForEach(msrcAbBugsToProcess, new ParallelOptions { MaxDegreeOfParallelism = 10 }, bugId =>
{
var vso = new WorkItemReporting(Config.VSTSAccessToken);
var workItemLinks = vso.GetWorkItemSourceCodeLinks(bugId);
});
推荐阅读
- http - 遵循方案的 URL 部分的名称?
- react-native - React 本机 iOS 无法在纱线工作区中自动链接
- spring-boot - 如何修复 - 无法加载驱动程序类:com.vertica.jdbc.Driver
- arrays - 如何将 YAML 数据解析为自定义 Bash 数据数组/哈希结构?
- ios - SWIFT 如何操作不同于用户当前显示的导航堆栈
- c# - 如何在 ASP.Net Core - CKEDITOR 5 上使用自定义上传适配器?
- python - 如何排除错误并将结果重定向到新文件
- amazon-web-services - AWS Fargate 网络 - 端口 80:连接被拒绝
- reactjs - 如何使用现有域上的子目录主页在服务器上提供反应应用程序?
- excel - 创建具有两个数组的动态 SumProduct 函数