该示例以 github dotnet https://github.com/dotnet/samples/blob/main/core/tutorials/Unloading/Host/Program.cs为基础,但是 PluginClass 中的方法GetMessage()已被重新设计,返回Task<string>和有以下主体:
using (var httpClient = new HttpClient())
{
var response = await httpClient.GetAsync(new Uri("https://jsonplaceholder.typicode.com/posts"));
var responseContent = await response.Content.ReadAsStringAsync();
var doc = JsonDocument.Parse(responseContent);
var models = doc.RootElement.EnumerateArray().Select(element => new Model
{
UserId = element.GetProperty("userId").GetInt32(),
Id = element.GetProperty("id").GetInt32(),
Title = element.GetProperty("title").GetString(),
Body = element.GetProperty("body").GetString()
}).ToList();
}
return "Hello from the unloadable plugin";
此代码运行良好,并且在调用 AssemblyLoadContext 后卸载了 Assembly Unload()。但是,如果我使用 System.Text.Json 或 Newtonsoft.Json,那么无论我等待多长时间,该 dll 都不会从上下文中卸载(我尝试了最多 100 秒,这对我来说是一个非常令人望而却步的时间)使用条件)。
使用 System.Text.Json 的有问题代码的示例如下:
using (var httpClient = new HttpClient())
{
var response = await httpClient.GetAsync(new Uri("https://jsonplaceholder.typicode.com/posts"));
var responseContent = await response.Content.ReadAsStringAsync();
var models = JsonSerializer.Deserialize<List<Model>>(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
}
return "Hello from the unloadable plugin";
使用 Newtonsoft.Json 的有问题代码的示例如下:
using (var httpClient = new HttpClient())
{
var response = await httpClient.GetAsync(new Uri("https://jsonplaceholder.typicode.com/posts"));
var responseContent = await response.Content.ReadAsStringAsync();
var models = JsonConvert.DeserializeObject<List<Model>>(responseContent);
}
return "Hello from the unloadable plugin";
您认为这种行为的原因是什么?可以通过任何方式避免吗?
一段时间后,我设法在 System.Text.Json 的上下文中找出问题(就我而言,这对我来说绝对没问题)。为了在处理用户类型时进行反射,会创建 JsonSerializerOptions 的长期实例(很可能这意味着选项缓存,更多详细信息请参见: https: //github.com/dotnet/runtime/issues/65323)。
ClearCache()为了解决这个问题, System.Text.Json.JsonSerializerOptionsUpdateHandler类中提供了一个方法。换句话说,在连接插件的主机程序集中(基于问题中的 dotnet/samples 的示例),Unload()只需在之前添加以下内容,问题就会消失: