【发布时间】:2016-02-19 06:53:31
【问题描述】:
我正在运行一个 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 Web Services。问题在于您使用
Parallel.For。让你的方法只打印“开始”和索引,然后等待Thread.Delay,然后打印“结束”,索引将展示同样的问题,依赖更少,代码更少。 -
顺便问一下,您的真实代码是否真的包含
await表达式?如果没有,对您的DoSomething方法的每次调用都将同步运行... -
没有。它没有。不知道如何在 Parallel.For 中使用 await
-
我在询问您的
DoSomething方法,您已将其标记为async方法,但它不包含await表达式,包括递归调用它时。听起来您可能需要阅读更多关于 async/await... -
在DoSomething里面,我还有其他包含await的操作。
标签: c# amazon-web-services task-parallel-library amazon-sqs parallel.foreach