gpt4 book ai didi

c# - System.Text.Json 无法访问处置 jsonDocument

转载 作者:行者123 更新时间:2023-12-04 09:00:22 25 4
gpt4 key购买 nike

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

“无法访问已释放的对象。对象名称:'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,
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<JsonDocument> ResponseMessage(HttpRequestMessage request, CancellationToken ct)
{
using (var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, 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(),
StatusCode = status.ToString(),
value = (int)status,
};
}
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://learn.microsoft.com/en-us/dotnet/api/system.text.json.jsondocument?view=netcore-3.1

Failure to properly dispose this object will result in the memory not being returned to the pool, which will increase GC impact across various parts of the framework.

关于c# - System.Text.Json 无法访问处置 jsonDocument,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63591180/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com