Mein Ziel ist es, Bilder aus einem Amazon Web Services-Bucket herunterzuladen.C# Task.WaitAll wartet nicht
ich den folgenden Code Funktion haben, die mehrere Bilder auf einmal herunterlädt:
public static void DownloadFilesFromAWS(string bucketName, List<string> imageNames)
{
int batchSize = 50;
int maxDownloadMilliseconds = 10000;
List<Task> tasks = new List<Task>();
for (int i = 0; i < imageNames.Count; i++)
{
string imageName = imageNames[i];
Task task = Task.Run(() => GetFile(bucketName, imageName));
tasks.Add(task);
if (tasks.Count > 0 && tasks.Count % batchSize == 0)
{
Task.WaitAll(tasks.ToArray(), maxDownloadMilliseconds);//wait to download
tasks.Clear();
}
}
//if there are any left, wait for them
Task.WaitAll(tasks.ToArray(), maxDownloadMilliseconds);
}
private static void GetFile(string bucketName, string filename)
{
try
{
using (AmazonS3Client awsClient = new AmazonS3Client(Amazon.RegionEndpoint.EUWest1))
{
string key = Path.GetFileName(filename);
GetObjectRequest getObjectRequest = new GetObjectRequest() {
BucketName = bucketName,
Key = key
};
using (GetObjectResponse response = awsClient.GetObject(getObjectRequest))
{
string directory = Path.GetDirectoryName(filename);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
if (!File.Exists(filename))
{
response.WriteResponseStreamToFile(filename);
}
}
}
}
catch (AmazonS3Exception amazonS3Exception)
{
if (amazonS3Exception.ErrorCode == "NoSuchKey")
{
return;
}
if (amazonS3Exception.ErrorCode != null && (amazonS3Exception.ErrorCode.Equals("InvalidAccessKeyId") || amazonS3Exception.ErrorCode.Equals("InvalidSecurity")))
{
// Log AWS invalid credentials
throw new ApplicationException("AWS Invalid Credentials");
}
else
{
// Log generic AWS exception
throw new ApplicationException("AWS Exception: " + amazonS3Exception.Message);
}
}
catch
{
//
}
}
Das Herunterladen der Bilder funktioniert alles gut, aber die Task.WaitAll
scheint weiterhin ignoriert, und der Rest des Codes werden ausgeführt werden - Das heißt, ich versuche, Dateien zu erhalten, die derzeit nicht vorhanden sind (da sie noch nicht heruntergeladen wurden).
Ich fand this Antwort auf eine andere Frage, die die gleiche wie meine scheint. Ich versuchte, die Antwort zu verwenden, um meinen Code zu ändern, aber es würde immer noch nicht auf das Herunterladen aller Dateien warten.
Kann mir jemand sagen, wo ich falsch liege?
Sollten Sie nicht zuerst alle Download-Aufgaben hinzufügen und nur * * danach ** warte auf den Abschluss? So mache ich es. Die Art, wie Sie vorgehen - Sie warten sofort, nachdem Sie einen neuen Thread in den Pool gestellt haben, um ihn zu vervollständigen - sieht wie eine synchrone Programmierung aus - mit anderen Worten, Sie profitieren nicht von Multithreading. Dies bezieht sich nicht direkt auf * nicht warten *, sondern ... als Bemerkung. – Veverke
@Veverke Ich bin neu in Tasks, also dachte ich, wenn ich sie alle hinzufügen würde, nehme an, es gäbe 10.000 Dateien, die ich herunterladen müsste, würden alle Aufgaben gleichzeitig laufen und zu viel für das System sein ??? - Aus diesem Grund beschließe ich, die Aufgaben in Stapeln auszuführen. – Rick
Nun, ich vermisste die Tatsache, dass Sie 2 warten, ich sah nur die erste. Ich frage dann etwas anderes: Warum brauchst du das in der Schleife? Hast du einmal versucht ohne es zu laufen? Versuchen Sie, das if in der for-Schleife zu kommentieren und sehen Sie, was passiert. Erhalten Sie Ausnahmen? – Veverke