Итак, я написал программу, которая выполняет HTTP API-вызовы к сервису, который мы используем на работе. Я пытался оптимизировать его с помощью Threadpool, и я вполне доволен результатом (по времени). Однако, как вы можете видеть ниже, call-url уникален для каждого вызова, потому что в конце он имеет идентификатор, который выбирается из списка. Значения списка считываются из локального файла, который не содержит дубликатов и в указанном списке нет дубликатов. Я знаю это, потому что я старался изо всех сил в отладке и видел, что все элементы уникальны. Я буквально понятия не имею, почему и мог бы действительно использовать некоторые разъяснения по этому вопросу. Кроме того, кажется, что значение, которое возвращается каждый раз, является последним элементом списка, каждый раз.
=> Попытался сделать пошаговый переход в VS, чтобы увидеть, было ли где-то, я использовал числа [0] вместоиз чисел [я], но ни один не найден. Хотя, когда я перешагнул через код вручную, я увидел, что возвращаемые значения не совпадают, но я не знаю почему?
=> Попытка сделать список глобальной переменной и заблокировать его, но в результате получаетсявсе то же самое, то же самое значение отправляется каждый раз.
//new code
object changeObjectsLock = new object();
List<Change> changeObjects = new List<Change>();
object amountOfCallsMade = new object();
int callCount = 0;
Parallel.For(0, changeIds.Count, index =>
{
try
{
string receivedJson;
httpWebRequest = (HttpWebRequest)WebRequest.Create(myApiUrl);
httpWebRequest.Headers["Auth"] = "token";
httpResponse = (HttpWebResponse)httpWebRequest.Getresponse();
using (StreamReader reader = new StreamReader(httpResponse.GetResponseStream()))
{
receivedJson = reader.ReadToEnd();
lock (changeObjectsLock)
{
changeObjects.Add(JsonConvert.Deserialize<Change>(receivedJson, jsonSettings));
}
}
lock (amountOfCallsMade)
{
++callCount;
Console.WriteLine($"Call No: {callCount}\tID: {changeIds[index]}");
}
}
catch (Exception) { }
});
//Old code
private static object changeObjectsLock = new object();
private static List<Change> changeObjects = new List<Change>();
private static object activeWorkersLock = new object();
private static int countOfActiveWorkers = 0;
private static object amountOfCallsMade = new object();
private static int callCount = 0;
private static object changeIdLock = new object();
private static List<string> changeIds = new List<string>();
static void Main(string[] args)
{
changeIds = GetChangeNumbers(); //changeIds is now populated
Action<object> getRequestAction = DoGetRequest;
GetAllRequests(getRequestAction, new object[] { null, httpWebRequest, httpResponse, token, jsonSettings });
}
private static void GetAllRequests(Action<object> action, object state)
{
object[] stateArr = state as object[];
do
{
lock (changeIdLock)
{
stateArr[0] = changeIds[0]
changeIds.RemoveAt(0);
}
object[] actionData = stateArr;
Action wrappedAction = () => { action(actionData); };
lock (activeWorkersLock)
{
++countOfActiveWorkers;
}
ThreadPool.QueueUserWorkItem(x => wrappedAction());
} while (changeIds.Count != 0)
lock (activeWorkersLock)
{
while (countOfActiveWorkers > 0)
{
Monitor.Wait(activeWorkersLock);
}
}
}
private static void DoGetRequest(object state)
{
try
{
object[] array = state as object[];
string number = array[0] as string;
HttpWebRequest httpWebRequest = array[1] as HttpWebRequest;
HttpWebResponse httpResponse = array[2] as HttpWebResponse;
string token = array[3] as string;
JsonSerializerSettings jsonSettings = array[4] array[4] as JsonSerializerSettings;
string receivedJson;
httpWebRequest = (HttpWebRequest)WebRequest.Create($"https://myapi.com/api/getInfo/{number}");
httpWebRequest.Headers["Auth"] = token;
httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (StreamReader reader = new StreamReader(httpResponse.GetResponseStream()))
{
receivedJson = reader.ReadToEnd();
lock (changeObjectsLock)
{
changeObjects.Add(JsonConvert.DeserializeObject<Change>(receivedJson, jsonSettings));
}
}
Console.WriteLine($"Current ID: {number}");
}
catch (Exception) { }
finally
{
lock (activeWorkersLock)
{
--countOfActiveWorkers;
Monitor.PulseAll(activeWorkersLock)
}
lock (amountOfCallsMade)
{
++callCount;
Monitor.PulseAll(amountOfCallsMade);
}
}
}
Желаемый вывод / результат состоит в том, что все вызовы должны быть на уникальных идентификаторах. Если вы посмотрите на строку записи, которая выдает «Текущий идентификатор: номер», она будет выводить одно и то же число каждый раз, независимо от того, что я пытаюсь сделать. Я хочу, чтобы каждый номер был уникальным.