问题描述
有人可以帮助我解决此错误吗? 直到现在我都无法解决。我不知道问题出在哪里。
“无法访问已处置的对象。对象名称:'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影响。