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);
}