5

我收到了很多没有上传到我的 AWS 存储桶的文件,但下面的代码始终显示完整。有谁知道这是怎么回事?如果上传总是完成,我应该如何确定上传是否失败?我确实看到了一些关于使用 transferutility.EndUpload 的信息,但我不确定如何使用它。另外我将如何实施重试?将对象状态传递给 BeginUpload?有什么帮助吗?

public class S3Upload
{
    private string awsAccessKeyId = "XXXXXX";
    private string awsSecretAccessKey = "XXXXXX";
    private string bucketName = System.Configuration.ConfigurationManager.AppSettings.Get("BucketName");
    private Amazon.S3.Transfer.TransferUtility transferUtility;
    private static log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

    public S3Upload()
    {
        // Initialize log4net.
        log4net.Config.XmlConfigurator.Configure();
        this.transferUtility = new Amazon.S3.Transfer.TransferUtility(awsAccessKeyId, awsSecretAccessKey);
        log.Info("S3 instance initiated");

    }

    public void UploadFile(string filePath, string toPath)
    {

        try
        {
            AsyncCallback callback = new AsyncCallback(uploadComplete);

            log.Info("S3 upload started...");
            log.InfoFormat("S3 filePath: {0}", filePath);
            log.InfoFormat("S3 toPath: {0}", toPath);


            var uploadRequest = new Amazon.S3.Transfer.TransferUtilityUploadRequest();
            uploadRequest.FilePath = filePath;
            uploadRequest.BucketName = bucketName;
            uploadRequest.Key = toPath;
            uploadRequest.StorageClass = Amazon.S3.Model.S3StorageClass.ReducedRedundancy;
            uploadRequest.AddHeader("x-amz-acl", "public-read");
            transferUtility.BeginUpload(uploadRequest, callback, null);
        }
        catch (AmazonS3Exception amazonS3Exception)
        {
              log.ErrorFormat("An Error, number {0}, occurred when creating a bucket with the message '{1}", amazonS3Exception.ErrorCode, amazonS3Exception.Message);    
        }
    }

    private void uploadComplete(IAsyncResult result)
    {
        var x = result;

        if (x.IsCompleted)
        {
            log.Info("S3 upload completed...");

        }
    }
}
4

2 回答 2

2

找到了解决办法!我添加了 transferUtility.EndUpload(ar) ,如果出错,它会将异常写入我的日志并重试 put 请求。

发出请求 PutObject 时出错。System.IO.IOException:无法将数据写入传输连接:现有连接被远程主机强行关闭。--->

public class S3Upload
{
    private string awsAccessKeyId = "XXXXX";
    private string awsSecretAccessKey = "XXXXX";
    private string bucketName = System.Configuration.ConfigurationManager.AppSettings.Get("BucketName");
    private Amazon.S3.Transfer.TransferUtility transferUtility;
    private static log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

    public S3Upload()
    {
        // Initialize log4net.
        log4net.Config.XmlConfigurator.Configure();
        this.transferUtility = new Amazon.S3.Transfer.TransferUtility(awsAccessKeyId, awsSecretAccessKey);
        log.Info("S3 instance initiated");

    }

    public void UploadFile(string filePath, string toPath)
    {

        try
        {
            AsyncCallback callback = new AsyncCallback(uploadComplete);

            log.Info("S3 upload started...");
            log.InfoFormat("S3 filePath: {0}", filePath);
            log.InfoFormat("S3 toPath: {0}", toPath);


            var uploadRequest = new Amazon.S3.Transfer.TransferUtilityUploadRequest();
            uploadRequest.FilePath = filePath;
            uploadRequest.BucketName = bucketName;
            uploadRequest.Key = toPath;
            uploadRequest.StorageClass = Amazon.S3.Model.S3StorageClass.ReducedRedundancy;
            uploadRequest.AddHeader("x-amz-acl", "public-read");
            IAsyncResult ar = transferUtility.BeginUpload(uploadRequest, callback, null);
            transferUtility.EndUpload(ar);
        }
        catch (AmazonS3Exception amazonS3Exception)
        {
              log.ErrorFormat("An Error, number {0}, occurred when creating a bucket with the message '{1}", amazonS3Exception.ErrorCode, amazonS3Exception.Message);
        }
    }

    private void uploadComplete(IAsyncResult result)
    {
        var x = result;
    }
}
于 2012-11-25T17:13:38.427 回答
2

BeginUpload 函数启动一个新线程,该线程启动并执行上传。调用 EndUpload 会导致当前线程阻塞,直到上传完成。此外,EndUpload 函数会捕获您从上传中获得的任何异常。

如果要调用 BeginUpload,则需要从单独的线程调用 EndUpload(),以免阻塞主线程。如果您打算阻塞主线程,只需调用 Upload() 函数而不是 APM 版本。

例如,生成一个新线程,它将等待上传完成。(请注意,它不必执行任何特定操作,只需捕获错误即可。)

public void UploadFile(string filePath, string toPath)
{

    try
    {
        AsyncCallback callback = new AsyncCallback(uploadComplete);

        log.Info("S3 upload started...");
        log.InfoFormat("S3 filePath: {0}", filePath);
        log.InfoFormat("S3 toPath: {0}", toPath);


        var uploadRequest = new Amazon.S3.Transfer.TransferUtilityUploadRequest();
        uploadRequest.FilePath = filePath;
        uploadRequest.BucketName = bucketName;
        uploadRequest.Key = toPath;
        uploadRequest.StorageClass = Amazon.S3.Model.S3StorageClass.ReducedRedundancy;
        uploadRequest.AddHeader("x-amz-acl", "public-read");
        IAsyncResult ar = transferUtility.BeginUpload(uploadRequest, callback, null);
        // transferUtility.EndUpload(ar);
        ThreadPool.QueueUserWorkItem(c =>
        {
             try
             {
                 transferUtility.EndUpload(ar);
             }
             catch (AmazonS3Exception ex)
             {
                 // Retry, log the error, etc.
             }
             catch (WebException ex)
             {
                 // Retry, log the error, etc.
             }
         });
    }
    catch (AmazonS3Exception amazonS3Exception)
    {
          log.ErrorFormat("An Error, number {0}, occurred when creating a bucket with the message '{1}", amazonS3Exception.ErrorCode, amazonS3Exception.Message);
    }
}

此外,该线程检查 WebException。我不知道您是否可以从 Beginupload 获得其中之一,但我正在处理的一些代码似乎在关注这些。(最好安全然后抱歉。)

另外,我发现您可以使用CurrPorts Utility对此进行测试。该实用程序可让您终止通往亚马逊的开放端口(尽管它会重试直到其配置的 MaxRetries)。

于 2013-05-20T16:08:28.247 回答