c# - 如何序列化任务使用 Json.NET?
问题描述
考虑
public class InQuestion<TType>
{
// JsonConverter(typeof CustomConverter))
public Task<TType> toConvert { get; set; }
}
如何使用 json.net (反)序列化此类?
我想我真正想要序列化的是底层的Task<T>.Result,然后可以用Task<T>.FromResult()反序列化。如果我要使用自定义 JsonConverter,我无法通过 Attribute 传递通用 TType,以在 JsonConverter 中重构(或检索)TType 对象。因此我被困住了。
问题来自这段代码:
public class Program
{
public class InQuestion<TType>
{
public Task<TType> toConvert { get; set; }
}
public class Result
{
public int value { get; set; }
}
public static async Task Main()
{
var questionable = new InQuestion<Result>();
questionable.toConvert = Task.Run(async () => new Result { value = 42 });
await questionable.toConvert;
string json = JsonConvert.SerializeObject(questionable);
Debug.WriteLine(json);
InQuestion<Result> back = JsonConvert.DeserializeObject(json, typeof(InQuestion<Result>)) as InQuestion<Result>;
Debug.Assert(back?.toConvert?.Result?.value == 42);
}
}
令我惊讶的是,它在调用 JsonConvert.DeserializeObject 期间停止了。https://github.com/JamesNK/Newtonsoft.Json/issues/1886讨论了这个问题并建议合理的“不要序列化/反序列化任务。”,但实际上并没有建议如何序列化底层任务< T >.结果。
解决方案
ATask
是对未来值的承诺,当然您不能序列化尚未提供的值。
因为InQuestion
对象包含一个Task
成员,所以您不能序列化和反序列化该InQuestion
对象。
解决方法是将结果序列化,并在反序列化后重建InQuestion
对象。
public static async Task Main()
{
var questionable = new InQuestion<Result>();
questionable.toConvert = Task.Run(async () => new Result { value = 42 });
Result result = await questionable.toConvert;
string json = JsonConvert.SerializeObject(result);
Result back = JsonConvert.DeserializeObject(json, typeof<Result>) as Result;
InQuestion<Result> reconstructed = new InQuestion<Result>()
{
toConvert = Task.FromResult(back)
};
}
推荐阅读
- r - 使用 R 在多个时间范围内求和
- java - 具有已定义行的 Oracle 嵌套选择
- django - 如何为每个用户制作个人资料
- spring-boot - 在 Springboot 中使用 Retrofit (Retrofit2) 客户端 (Kotlin) 实现双向 TLS
- mysql - Mysql 连接器 8.0 和 Python 3.8
- android - 有没有办法在 Realm 中使用并行流?
- java - 从 Java 多项目构建 Gradle rmp
- angularjs - 如何冻结角度材料数据表两侧的列?
- python - 如何使用 get_FOO_display() 在 Django 中访问未实例化的模型
- vue.js - VUE:编译远程组件有什么安全友好的方法吗?