Вам необходимо заблокировать доступ к внешнему ресурсу, выполнив что-то вроде следующего.
Согласно комментарию @AlexSikilinda _witClient не должен быть потокобезопасным.
То, что вы делаете, хотя то, что вы можете создавать несколько потоков, не означает, что вы должны, я бы получил время, о том, что вы делаете с параллельной обработкой в вашем коде и без нее,
Имейте в виду, что если вы используете не поточно-ориентированные внешние ресурсы и блокируете, то это может быть столь же медленным, как и в обычном цикле for. Вам нужно протестировать оба сценария.
Добавьте объект вне ваших методов, чтобы разрешить доступ к объекту блокировки из каждого потока, это поможет управлять доступом к классу, не поддерживающему поток.
vso = new WorkItemReporting(Config.VSTSAccessToken);
private readonly object _witLock = new object();
В последующем вы НЕ хотите ставить блокировку вокруг всего содержимого методов, как у меня, в противном случае вы определенно тратите свое время, используя Parallel для этого куска кода.
Исходя из того, что вы думаете, это должно остановить исключения.
Вам необходимо изменить код так, чтобы в блокировке находился только вызов _witClient. Поэтому просто объявите переменную workItem вне блокировки с соответствующим ей типом, а затем оберните вызов workItem = _witClient.GetWorkItemAsync (bugId, null, null, WorkItemExpand.Relations) .Result; в вашем коде блокировки.
public List<string> GetWorkItemSourceCodeLinks(int bugId)
{
var workItemSourceCodeLinks = new List<string>();
lock (_witLock)
{
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);
}
}
}
}
}
Удачи