多次运行函数时无法访问已释放的对象

Rob*_*lls 1 c# amazon-web-services asp.net-core

我有一个 ASP.NET Core 2.1 应用程序,但收到错误:

无法访问已处置的对象。对象名称:“Amazon.S3.AmazonS3Client”

当尝试调用我的 AWS S3 读取对象服务时。该服务第一次可以正常工作,但第二次及以后就会失败。

我在startup.cs中有以下内容:

services.AddSingleton<IAWSService, AWSService>();
services.AddAWSService<IAmazonS3>();
Run Code Online (Sandbox Code Playgroud)

(我尝试配置 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;

    }
}
Run Code Online (Sandbox Code Playgroud)

}

我第一次运行该函数时,断点显示 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)
    }
}
Run Code Online (Sandbox Code Playgroud)

Cod*_*ter 6

这是因为您将 的_s3Client用法包装在一个using块中,该块随后会处理该实例。

不要那样做。

让你的 IoC 容器为你处理这个问题,而不是显式或隐式地处理你的_s3Client.

考虑到Amazon .NET AWS SDK 的 AmazonS3 线程安全吗?的答案,将包装器注册为单例就可以了。是是的”。这意味着您的应用程序在任何给定时间都有一个您的实例,并且该类将为所有请求AWSService使用相同的实例。IAmazonS3

然后你只需要在应用程序生命周期结束时处置它,你的 IoC 容器就会处理它。