我收到很多未上传到我的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...");
}
}
}
答案 0 :(得分:1)
找到了修复!我添加了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;
}
}
答案 1 :(得分:1)
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之前重试)。