Amazon S3 TransferUtility.Upload зависает в C # - PullRequest
11 голосов
/ 03 декабря 2011

Итак, я пишу приложение для миграции, чтобы взять некоторые данные из нашего локального хранилища и загрузить их в Amazon.Все работает нормально, за исключением случаев, когда я попадаю в файлы размером более 15 мегабайт (мегабайт, да, НЕ Гигантские), приложение зависает.

Это на C #, довольно просто.

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".Как я уже сказал, странно то, что это прекрасно работает для небольших файлов, но блокирует все для больших.

Ответы [ 2 ]

4 голосов
/ 21 апреля 2012

Попробуйте использовать метод BeginUpload вместо Upload.

        transferUtility.BeginUpload(request, new AsyncCallback(uploadComplete), null );
    }
    private void uploadComplete(IAsyncResult result)
    {
        var x = result;
    }

Настройте утилиту передачи и UploadProgressEvent, как вы это делали ранее.Используйте метод Invoke в обработчике прогресса, как вы это сделали.Если вы используете BeginUpdate () вместо Update (), это предотвратит зависание приложения при первом обновлении вашей формы.Я нигде не мог найти это решение, поэтому надеюсь, что оно вам подходит.

0 голосов
/ 03 декабря 2011

Является ли 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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...