Я запускаю цикл Parallel for, который изначально запускается на время = количество процессоров и выполняет длительную операцию. Каждая задача, когда закончена, проверяет больше задач и, если она найдена, снова вызывает себя.Непредсказуемые результаты при использовании Parallel.For
Вот как мой код выглядит следующим образом:
static void Main(string[] args)
{
Int32 numberOfProcessors = Environment.ProcessorCount;
Parallel.For(0, numberOfProcessors, index => DoSomething(index, sqsQueueURL));
}
private async static Task DoSomething(int index, string queueURL)
{
var receiveMessageRequest = new ReceiveMessageRequest { QueueUrl = queueURL, WaitTimeSeconds = 20, MaxNumberOfMessages = 1, VisibilityTimeout = 1200 };
AmazonSQSClient sqsClient = new AmazonSQSClient(new AmazonSQSConfig { MaxErrorRetry = 4 });
var receiveMessageResponse = sqsClient.ReceiveMessage(receiveMessageRequest);
foreach (var msg in receiveMessageResponse.Messages)
{
PerformALongRunningTask......
//delete the message
DeleteMessageRequest deleteMessageRequest = new DeleteMessageRequest(queueURL, msg.ReceiptHandle);
AmazonSQSClient sqsDeleteClient = new AmazonSQSClient();
sqsDeleteClient.DeleteMessage(deleteMessageRequest);
//Do it again
DoSometing(index,queueURL)
}
}
Я получаю очень непредсказуемые результаты. Он никогда не завершает все задачи. Он выходит, прежде чем завершить все.
Что я здесь делаю неправильно?
Более короткий код:
static Int32 TimesToLoop = 143;
static void Main(string[] args)
{
Int32 numberOfProcessors = Environment.ProcessorCount;
Parallel.For(0, numberOfProcessors, index => DoSomething(index));
Console.Read();
}
private async static Task DoSomething(int index)
{
if(TimesToLoop == 0)
{
return;
}
Console.WriteLine(index);
Interlocked.Decrement(ref TimesToLoop);
DoSomething(index++);
return;
}
Первое, что нужно сделать: уменьшить это до краткого, но полного примера, который вообще не включает веб-службы Amazon. Проблема заключается в том, что вы используете 'Parallel.For'. Создав свой метод, просто напечатайте «start» и индекс, затем ожидайте «Thread.Delay», затем распечатайте «окончание», и индекс продемонстрирует ту же проблему, с меньшим количеством зависимостей и меньшим количеством кода. –
Действительно ли ваш реальный код содержит выражения 'await', кстати? Если это не так, каждый вызов вашего метода «DoSomething» будет выполняться синхронно ... –
Нет. Не знаю, как использовать ожидание в Parallel.For – Asdfg