我正在尝试将使用Async / Await反序列化对象的方法转换为字符串。
public static T DeserializeObject<T>(string xml)
{
using (StringReader reader = new StringReader(xml))
{
using (XmlReader xmlReader = XmlReader.Create(reader))
{
DataContractSerializer serializer = new DataContractSerializer(typeof(T));
T theObject = (T)serializer.ReadObject(xmlReader);
return theObject;
}
}
}
答案 0 :(得分:14)
大多数序列化API没有async
实现,这意味着你唯一能做的就是 wrap 一个同步方法。例如:
public static Task<T> DeserializeObjectAsync<T>(string xml)
{
using (StringReader reader = new StringReader(xml))
{
using (XmlReader xmlReader = XmlReader.Create(reader))
{
DataContractSerializer serializer =
new DataContractSerializer(typeof(T));
T theObject = (T)serializer.ReadObject(xmlReader);
return Task.FromResult(theObject);
}
}
}
这不是实际异步 - 它只是满足所需的API。如果您有选项,在结果可能经常是同步/
的情况下,最好使用ValueTask<T>
无论哪种方式,您都应该能够执行以下操作:
var obj = await DeserializeObject<YourType>(someXml);
Debug.WriteLine(obj.Name); // etc
无需知道实际实现是同步还是异步。
答案 1 :(得分:1)
一个小样本,非常原始的方式:
public delegate T Async<T>(string xml);
public void Start<T>()
{
string xml = "<Person/>";
Async<T> asyncDeserialization = DeserializeObject<T>;
asyncDeserialization.BeginInvoke(xml, Callback<T>, asyncDeserialization);
}
private void Callback<T>(IAsyncResult ar)
{
Async<T> dlg = (Async<T>)ar.AsyncState;
T item = dlg.EndInvoke(ar);
}
public T DeserializeObject<T>(string xml)
{
using (StringReader reader = new StringReader(xml))
{
using (XmlReader xmlReader = XmlReader.Create(reader))
{
DataContractSerializer serializer = new DataContractSerializer(typeof(T));
T theObject = (T)serializer.ReadObject(xmlReader);
return theObject;
}
}
}
定义一个委托并使用它来回调/使用回调调用。
使用下一版本的C#,您可以使用async关键字来异步运行代码。
答案 2 :(得分:0)
当您使用string
作为数据源时,执行异步操作只会带来更多开销,并且不会为您提供任何内容。
但是如果您从流中读取数据,则可以从源流复制到MemoryStream
(缓冲所有数据),然后从MemoryStream
反序列化,这将增加内存使用量但会降低你将阻止线程的时间。
答案 3 :(得分:-2)
您可以返回
Task.FromResult(theObject)