System.Text.Json无法访问处置jsonDocument

问题描述

有人可以帮助我解决此错误吗? 直到现在我都无法解决。我不知道问题出在哪里。

“无法访问已处置的对象。对象名称:'JsonDocument'”

我刚开始使用“ Sytem.Text.Json”,这就是为什么我仍在学习并且想知道如何正确使用它的原因。

谢谢。

  public static async Task<JsonElement> ParseJsonData(string api,CancellationToken ct)
    {
        clientHandler = new HttpClientHandler()
        {
            UseProxy = Proxy.IsUseProxy ? true : false,Proxy = Proxy.IsUseProxy ? new WebProxy($"{Proxy.ProxyHost}:{Proxy.ProxyPort}") : null,//ServerCertificateCustomValidationCallback = (sender,certificate,chain,errors) => { return true; },// SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls
        };
        var uri = new Uri(api,UriKind.Absolute);
        utils.SetConnection(uri);
        client = new HttpClient(clientHandler);
        using (var request = new HttpRequestMessage(HttpMethod.Get,uri))
        {
            AddRequestHeaders(request,uri);
            return await ResponseMessage(request,ct);
        }
    }
    private static async Task<JsonElement> ResponseMessage(HttpRequestMessage request,CancellationToken ct)
    {
        using (var response = await client.SendAsync(request,HttpCompletionOption.ResponseHeadersRead,ct).ConfigureAwait(false))
        {
            ct.ThrowIfCancellationRequested();
 
            using (var content = response.Content)
            {
                var stream = await content.ReadAsStreamAsync().ConfigureAwait(false);
                var json = await ParseStream(stream,response);

                return json.RootElement;
            }
        }
    }

    private static async Task<JsonDocument> ParseStream(Stream stream,HttpResponseMessage response)
    {
        if (stream == null || stream.CanRead == false)
        {
            return default;
        }

        HttpStatusCode status = response.StatusCode;
        StatusCode.status = status.ToString();
        StatusCode.value = (int)status;

        using (var json = await JsonDocument.ParseAsync(stream).ConfigureAwait(false))
        {
            if (!response.IsSuccessStatusCode)
            {
                throw new ApiException()
                {
                    Content = json.RootElement.ToString(),StatusCode = status.ToString(),value = (int)status,};
            }
            return json;
        }
    }

更新:(这是我尝试过的)

     public static async Task<JsonDocument> ParseJsonData(string api,CancellationToken ct)
        {
            clientHandler = new HttpClientHandler()
            {
                UseProxy = Proxy.IsUseProxy ? true : false,ServerCertificateCustomValidationCallback = (sender,errors) => { return true; }
                // SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls
            };
            var uri = new Uri(api,UriKind.Absolute);
            utils.SetConnection(uri);
            client = new HttpClient(clientHandler);

            using (var request = new HttpRequestMessage(HttpMethod.Get,uri))
            {
                AddRequestHeaders(request,uri);
                return await ResponseMessage(request,ct);
            }
        }
        private static async Task<JsonDocument> ResponseMessage(HttpRequestMessage request,CancellationToken ct)
        {
            using (var response = await client.SendAsync(request,ct).ConfigureAwait(false))
            {
                ct.ThrowIfCancellationRequested();
                HttpStatusCode status = response.StatusCode;
                
                using (var content = response.Content)
                {
                    var stream = await content.ReadAsStreamAsync().ConfigureAwait(false);

                    if (stream == null || stream.CanRead == false) { return default; }

                    var options = new JsonDocumentOptions { AllowTrailingCommas = true };
                    var json = await JsonDocument.ParseAsync(stream,options).ConfigureAwait(false);
                    
                    if (!response.IsSuccessStatusCode)
                    {
                        throw new ApiException()
                        {
                            Content = json.RootElement.ToString(),};
                    }
                    return json;
                }
            }
        }

   public static async Task<test> GetData(string id,CancellationToken ct)
    {
        string API = $"https://www.test.com/api/videos/{id}";

        using (var root = await MyClientHelper.ParseJsonData(API,ct))
        {
            var json = root.RootElement;

            //here i can access the root and dispose after

            return new test()
            {
                /////
            }
        }
    }

解决方法

using是这样工作的。当您离开using子句时,该对象将被处置。那是故意的。

所以请考虑您的代码:

using (var json = await JsonDocument.ParseAsync(stream).ConfigureAwait(false))
        {
            if (!response.IsSuccessStatusCode)
            {
                throw new ApiException()
                {
                    Content = json.RootElement.ToString(),StatusCode = status.ToString(),value = (int)status,};
            }
            return json; <------ the moment you return it you also dispose it
        }

因此,当您尝试在外部访问它时,会出现错误:

    var json = await ParseStream(stream,response);
    // here your object is already disposed
    return json.RootElement;

解决方案:在存在解析函数之前,返回您的json。 JsonDocument对象不应在using子句之外使用。

您不应忽略将对象作为解决方法:https://docs.microsoft.com/en-us/dotnet/api/system.text.json.jsondocument?view=netcore-3.1

未能正确处理该对象将导致内存没有返回到池中,这将增加对框架各个部分的GC影响。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...