[英]Cannot access a disposed object when running function more than once
我有一个ASP.NET Core 2.1应用程序,但出现错误:
无法访问已处置的对象。 对象名称:“ Amazon.S3.AmazonS3Client”
尝试调用我的AWS S3读取对象服务时。 该服务第一次运行,第二次及以后失败。
我在startup.cs中具有以下内容:
services.AddSingleton<IAWSService, AWSService>();
services.AddAWSService<IAmazonS3>();
(我尝试将AsScoped()配置为无效。)
这是引起问题的功能:
public class AWSService : IAWSService
{
private readonly IAmazonS3 _s3Client;
public AWSService(IAmazonS3 s3Client)
{
_s3Client = s3Client;
}
public async Task<byte[]> ReadObjectFromS3Async(string bucketName, string keyName)
{
try
{
GetObjectRequest request = new GetObjectRequest
{
BucketName = bucketName,
Key = keyName
};
using (_s3Client)
{
MemoryStream ms = new MemoryStream();
using (var getObjectResponse = await _s3Client.GetObjectAsync(request))
{
getObjectResponse.ResponseStream.CopyTo(ms);
}
var download = new FileContentResult(ms.ToArray(), "application/pdf");
return download.FileContents;
}
}
catch (AmazonS3Exception e)
{
Console.WriteLine("Error encountered ***. Message:'{0}' when writing an object", e.Message);
}
catch (Exception e)
{
Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message);
}
return null;
}
}
}
我第一次运行该函数时,一个断点显示this.s3client没有被处理,但是随后尝试运行此函数表明s3client被处理了,因此出现了错误。
更新资料
我从控制器调用此函数:
public class CorrespondenceItemController : Controller
{
private IAWSService _awsService;
public CorrespondenceItemController(IAWSService aWSService)
{
_awsService = aWSService;
}
public async Task<ActionResult<dynamic>> Send([FromBody]CorrespondenceItemSendViewModel model)
{
var attachment = await _awsService.ReadObjectFromS3Async(bucket, key)
}
}
这是因为您将_s3Client
的用法包装在using
块中,该块随后将处理该实例。
不要那样做
通过不显式或隐式处理_s3Client
,让IoC容器为您处理_s3Client
。
鉴于对Amazon .NET AWS SDK的AmazonS3线程安全吗?的答案,可以将包装器注册为单例。 是是的”。 这意味着您的应用程序在任何给定时间都有一个AWSService
实例,并且该类将对所有请求使用相同的IAmazonS3
实例。
然后,您只需要在应用程序生命周期结束时进行处理,您的IoC容器就可以处理它。
使用是调用dispose的try / finally块的简写。
using (_s3Client) { }
这一行表示,创建一个客户端并在花括号{}中执行代码。 然后调用.Dispose()
将其关闭。
这意味着您的客户端将根据Dispose()
方法的操作而关闭/关闭。
如果要保持连接打开,则不应该using
块,或者可以将注入的客户端更改为客户端工厂,让它在每次调用时创建一个新客户端,或者每次使用时手动打开/关闭连接它。
using (_s3Client){}
一旦using
块完成执行,则将调用dispose方法
使用等于
var ob = new Object()
try
{
ob = null;
}
finally
{
if (ob!= null)
((IDisposable)ob).Dispose();
}
使用_s3Client删除,因为将其保留在using块中而已被处置。 因为您的目标是重用它,所以不要简单地对其进行处置。
using (var getObjectResponse = await _s3Client.GetObjectAsync(request))
using (MemoryStream ms = new MemoryStream())
{
getObjectResponse.ResponseStream.CopyTo(ms);
FileContentResult download = new FileContentResult(ms.ToArray(), "application/pdf");
return download.FileContents;
}
如果要将s3Client用作Singleton,请使用using删除。 这样,您将在应用程序生命周期中拥有一个s3Client对象。 如果s3Client在其中存储任何对象,请小心。 这可能会导致资源问题。
公共类AWSService:IAWSService {私有只读IAmazonS3 _s3Client;
public AWSService(IAmazonS3 s3Client) { _s3Client = s3Client; } public async Task<byte[]> ReadObjectFromS3Async(string bucketName, string keyName) { try { GetObjectRequest request = new GetObjectRequest { BucketName = bucketName, Key = keyName }; MemoryStream ms = new MemoryStream(); using (var getObjectResponse = await _s3Client.GetObjectAsync(request)) { getObjectResponse.ResponseStream.CopyTo(ms); } var download = new FileContentResult(ms.ToArray(), "application/pdf"); return download.FileContents; } catch (AmazonS3Exception e) { Console.WriteLine("Error encountered ***. Message:'{0}' when writing an object", e.Message); } catch (Exception e) { Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message); } return null; }
}
如果要为每个调用创建一个新对象,请从IOC上下文中删除s3Client注册。
公共类AWSService:IAWSService {
public async Task<byte[]> ReadObjectFromS3Async(string bucketName, string keyName) { try { GetObjectRequest request = new GetObjectRequest { BucketName = bucketName, Key = keyName }; using (var s3Client= new s3Client()/*I don't know how you create*/) { MemoryStream ms = new MemoryStream(); using (var getObjectResponse = await s3Client.GetObjectAsync(request)) { getObjectResponse.ResponseStream.CopyTo(ms); } var download = new FileContentResult(ms.ToArray(), "application/pdf"); return download.FileContents; } } catch (AmazonS3Exception e) { Console.WriteLine("Error encountered ***. Message:'{0}' when writing an object", e.Message); } catch (Exception e) { Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message); } return null; }
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.