我有一个上传多个文件的表单。我的模型有List<HttpPostedFileBase>
名为SchemaFileBases
,正确绑定。我需要将这些文件上传到s3,并希望并行执行。我无法使用asyc并等待,因为此代码是从ASP.Net和基于队列的应用程序运行的,该应用程序当前没有async / await支持(正在处理它)。
如果我将下面的foreach
更改为Parallel.ForEach(this.SchemaFileBases, schemaFileBase => {
...那么我会有一些蠢蠢欲动。这两个文件最终被捣碎了。每个文件在上传后都会包含一些其他文件内容。 AwsDocument
正在其他地方并行使用,所以我不认为它与此有关。每个AwsDocument
都有自己的AmazonS3Client
。
public override void UploadToS3(IMetadataParser parser)
{
string hash;
string key;
foreach (var schemaFileBase in this.SchemaFileBases)
{
AwsDocument aws = new AwsDocument(AwsBucket.Received);
hash = schemaFileBase.InputStream.Md5Hash().ToByteArray().ToHex();
key = String.Format("{0}/{1}", this.S3Prefix, schemaFileBase.FileName);
Stream inputStream = schemaFileBase.InputStream;
aws.UploadToS3(key, inputStream, hash);
}
}
我的同事怀疑这与InputStream
HttpPostedFileBase
的实施方式有关。也许它不是线程安全的,并且流都同时从原始请求中读取?我无法想象MS会这样做。
多线程版本:
public override void UploadToS3(IMetadataParser parser)
{
Parallel.ForEach(this.SchemaFileBases, f =>
{
AwsDocument aws = new AwsDocument(AwsBucket.Received);
string hash = f.InputStream.Md5Hash().ToByteArray().ToHex();
string key = String.Format("{0}/{1}", this.S3Prefix, f.FileName);
Stream inputStream = f.InputStream;
aws.UploadToS3(key, inputStream, hash);
});
}
以上解决方案是我尝试多线程的。不起作用(文件混乱起来很奇怪)。