Amazon S3 TransferUtility.Upload在C#中挂起

所以我正在编写一个迁移应用程序,从我们的本地存储中获取一些数据并将其上传到亚马逊。 一切都运行正常,除了一旦我进入大于15兆的文件(megs,是的,不是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 megs需要40秒,所以我期待30兆的测试文件,也许2分钟…但10分钟后,没有爱。

任何建议都将不胜感激,不幸的是,我将处理大量超过50兆的文件。

请注意,如果我在Visual Studio .net的AWS资源管理器中,我可以手动上传50+ megs的文件而不会出现任何问题并且相对较快。


所以这很“有意思”……在进一步审查中,我的50兆字节文件上传得很好。 它附加到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 ”。 就像我说的那样,奇怪的是,这适用于较小的文件但是将所有内容锁定为较大的文件。

尝试使用BeginUpload方法而不是Upload。

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

像以前一样设置传输实用程序和UploadProgressEvent。 像你一样在进程处理程序中使用Invoke方法。 如果您使用BeginUpdate()而不是Update(),它将阻止应用程序挂起对表单的第一次更新。 我无法在任何地方找到这个解决方案,所以我希望它适合你。

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