Amazon S3 TransferUtility.Upload зависает на С#
Итак, я пишу приложение для переноса, чтобы взять некоторые данные из нашего локального хранилища и загрузить его в Amazon. Все работает нормально, за исключением случаев, когда я попадаю в файлы размером более 15 мегабайт (мега, да, NOT Gigs), приложение замораживается.
Это на С#, довольно просто.
var transferRequest = new TransferUtilityUploadRequest
{
Key = firstKey,
FilePath = fileName,
BucketName = ContentBucket,
Timeout = 3600000,
ContentType = GetContentTypeForFileExtension(fileName)
};
transferRequest.UploadProgressEvent += DisplayFileProgress;
transferUtil.Upload(transferRequest);
Как я уже сказал, отлично работает для файлов размером 15 мегабайт или меньше... но на больших, он просто останавливается и сидит на команде "Загрузить" навсегда. 15 мегабайт занимает 40 секунд, поэтому я ожидал, что тестовый файл размером 30 мегабайт займет, может быть, 2 минуты... но через 10 минут никакой любви.
Любые советы будут оценены, так как, к сожалению, я буду иметь дело с большим количеством файлов размером более 50 мегабайт.
Обратите внимание, что если я в AWS Explorer в Visual Studio.net, я могу вручную загружать файлы из 50+ мегабайт без каких-либо проблем и относительно быстро.
Итак, это "интересно"... В ходе дальнейшего обзора мои файлы размером 50 мегабайт загружаются просто отлично. Его код, который я прикреплял к UploadProgressEvent, который фактически заставляет замораживать вещи, потому что, если я его прокомментирую, тогда загрузка 50 мегабайт без проблем.
Если я оставлю этот код, 15 мегабайт файлов покажут их прогресс на индикаторе выполнения. Но все, что превышает 15 мегабайт, фактически заставляет все приложение замерзать. Может ли кто-нибудь сказать мне, что может быть проблемой с кодом, который обрабатывает обновление строки выполнения?
private void DisplayFileProgress(object sender, UploadProgressArgs args)
{
pbFileProgress.Invoke((MethodInvoker)delegate {
pbFileProgress.Value = args.PercentDone;
pbFileProgress.Refresh(); });
}
И я просто устанавливаю "transferRequest.UploadProgressEvent += DisplayFileProgress
". Как я уже сказал, что странно, что это работает отлично для небольших файлов, но блокирует все для более крупных.
Ответы
Ответ 1
Попробуйте использовать метод BeginUpload вместо Upload.
transferUtility.BeginUpload(request, new AsyncCallback(uploadComplete), null );
}
private void uploadComplete(IAsyncResult result)
{
var x = result;
}
Установите свою утилиту передачи и UploadProgressEvent, как и раньше. Используйте метод Invoke в обработчике выполнения так же, как и вы. Если вы используете BeginUpdate() вместо Update(), это предотвратит зависание приложения при первом обновлении формы. Я не мог найти это решение нигде, поэтому надеюсь, что это сработает для вас.
Ответ 2
Является ли DisplayFileProgress потокобезопасным? Я считаю (смотря на какой-то старый код), что обратный вызов вызывается каждым потоком загрузки независимо.
Этот код ниже является частью небольшой утилиты, которую мы используем для загрузки файлов размером от 5 МБ до 1-2 ГБ или около того. Это не удивительно отличается от вашего, но, возможно, это может помочь.
var writerlock = new object();
using (var tu = new TransferUtility(amazonS3Client, tuconfig))
{
var turequest = new TransferUtilityUploadRequest()
.WithBucketName(bucket)
.WithFilePath(file)
.WithKey(Path.GetFileName(file))
.WithStorageClass(S3StorageClass.ReducedRedundancy)
.WithPartSize(5 * 1024 * 1024)
.WithAutoCloseStream(true)
.WithCannedACL(S3CannedACL.PublicRead);
tuconfig.NumberOfUploadThreads = Environment.ProcessorCount - 1;
// show progress information if not running batch
if (interactive)
{
turequest.UploadProgressEvent += (s, e) =>
{
lock (writerlock)
{
... our progress routine ...
}
};
}
tu.Upload(turequest);
}