10

I am trying to convert this method that deserializes an object into a string with 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;
            }
        }
    }
2
  • Do you mean Async/Await, or just any sort of asynchronous pattern? Commented Aug 9, 2012 at 12:58
  • I am looking for Async/Await Jeff, thanks. Commented Aug 9, 2012 at 13:36

4 Answers 4

17

Most serialization APIs do not have async implementations, which means the only thing you can really do is wrap a sync method. For example:

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);
        }
    }
}

This isn't actually async - it just meets the required API. If you have the option, using ValueTask<T> is preferable in scenarios where the result may often be synchronous/

Either way, you should then be able to do something like:

var obj = await DeserializeObject<YourType>(someXml);
Debug.WriteLine(obj.Name); // etc

without needing to know whether the actual implementation was synchronous or asynchronous.

Sign up to request clarification or add additional context in comments.

2 Comments

Noted that the method is still sync because there is no "await" syntax for switching context. It's just a sync Task and meaningless for await it.
@shtse8 yes, that's a fair comment - I've clarified
2

A little sample, pretty primitive way:

    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;
            }
        }
    }

you define a delegate and using it to Begin/End invoke using callbacks.

using the next versions of C# you can use the async keyword to get your code run asynchronously.

1 Comment

Tamir, I am using the next version of C# in Windows8. Could you give me an example using await and async? That is what I am looking for. Thank you.
0

As you are working with a string as data source doing things async would only introduce more overhead and give you nothing for it.

But if you where reading from a stream you could copy from the source stream to a MemoryStream(buffering all data), then deserialize from the MemoryStream, that would increase the memory usage but would lower the amount of time you will block the thread.

Comments

-5

You can return

Task.FromResult(theObject)

1 Comment

This will run synchronously.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.