【问题标题】:Amazon S3 TransferUtility.Upload hangs in C#Amazon S3 TransferUtility.Upload 在 C# 中挂起
【发布时间】:2012-01-11 19:40:58
【问题描述】:

所以我正在编写一个迁移应用程序,从我们的本地存储中获取一些数据并将其上传到亚马逊。一切正常,除非我进入大于 15 兆的文件(兆,是的,不是 Gigs),应用程序冻结。

这是用 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 兆的文件。

请注意,如果我在 Visual Studio .net 中的 AWS Explorer 中,我可以手动上传 50 多兆的文件而不会出现任何问题,而且速度相对较快。


所以这很“有趣”...经过进一步审查,我的 50 meg 文件上传得很好。它是我附加到 UploadProgressEvent 的代码,实际上导致事情冻结,因为如果我将其注释掉,那么 50 meg 文件上传没有问题。

如果我保留此代码,则 15 个 meg 文件会在进度条上显示它们的进度。但任何大于 15 兆的内容实际上都会导致整个应用程序冻结。谁能告诉我处理进度条更新的代码可能有什么问题?

private void DisplayFileProgress(object sender, UploadProgressArgs args)
{
    pbFileProgress.Invoke((MethodInvoker)delegate { 
        pbFileProgress.Value = args.PercentDone; 
        pbFileProgress.Refresh(); }); 
}

我只是设置“transferRequest.UploadProgressEvent += DisplayFileProgress”。就像我说的那样,奇怪的是这对于较小的文件来说很好,但会为较大的文件锁定所有内容。

【问题讨论】:

  • 出于兴趣,您是否尝试过通过流而不是文件上传?这显然会阻碍异步上传块的能力。很想知道这是否有效。
  • 我没有尝试过,不知道如何设置...我想我会在星期一深入研究。虽然看起来 30 兆的文件应该不会造成任何困难,不是吗?
  • 不,当然不应该。但是,如果您阅读有关 S3 论坛的信息,您会发现很多人都有类似的问题。碰巧的是,我的 NAS 系统的软件也无法处理将大于 10MB 的文件上传到 S3,而 Cloudberry 软件处理得很好。我认为尝试流所需要做的就是使用 File.Open 打开它,然后在 TransferUtilityUploadRequest 上设置流属性而不是文件名属性。

标签: c# .net amazon-s3


【解决方案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 MB 到 1-2 GB 左右文件的小型实用程序的一部分。它与您的并没有太大的不同,但也许会有所帮助。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-15
      • 1970-01-01
      • 2014-01-18
      • 1970-01-01
      • 2012-03-12
      • 2010-11-14
      • 1970-01-01
      相关资源
      最近更新 更多