猿问

多次运行函数时无法访问已处置的对象

我有一个 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 已释放,因此出现错误。


心有法竹
浏览 152回答 4
4回答

POPMUISE

那是因为您将_s3Client's 的用法包装在一个using块中,然后再处理该实例。不要那样做。让您的 IoC 容器为您处理,而不是显式或隐式地处理您的_s3Client.考虑到亚马逊 .NET AWS SDK 的 AmazonS3 线程安全吗?是是的”。这意味着您的应用程序AWSService在任何给定时间都有一个您的实例,并且该类将对IAmazonS3所有请求使用相同的实例。然后您只需要在应用程序生命周期结束时处理它,您的 IoC 容器就会处理它。

侃侃无极

Using 是调用 dispose 的 try/finally 块的简写。

慕哥6287543

&nbsp;using (_s3Client){}&nbsp;一旦 using阻塞完成执行,就会调用 dispose 方法using 语句等于&nbsp; var ob = new Object()&nbsp;try&nbsp;{&nbsp; &nbsp;ob = null;&nbsp;}&nbsp;finally&nbsp;{&nbsp; if (ob!= null)&nbsp; &nbsp; ((IDisposable)ob).Dispose();&nbsp;}

慕田峪9158850

使用 _s3Client 删除,当您将其保存在 using 块中时,它会被处理掉。由于您的目标是重复使用它,所以不要丢弃,简单。using (var getObjectResponse = await _s3Client.GetObjectAsync(request))using (MemoryStream ms = new MemoryStream()){&nbsp; &nbsp; getObjectResponse.ResponseStream.CopyTo(ms);&nbsp; &nbsp; FileContentResult download = new FileContentResult(ms.ToArray(), "application/pdf");&nbsp; &nbsp; return download.FileContents;}
随时随地看视频慕课网APP
我要回答