Search code examples
c#windows-8async-ctpasync-await

Deserialization and Async/Await


In my app (Windows 8 Metro) I store some objects in the local Folder in a serialized format. Here's the method to read then back (see below).

If I call this method with Task.Run, I can get the object:

var entity= Task.Run<Entity>(() => GetASync<Entity>(file)).Result;

but if I use the await keyword, it's not working - on the line A (ReadObject) in the method the thread stops and exit with no error or exception:

var entity= await GetASync<Entity>(file);

Maybe I don't use await / async as it's recommended?

The method

private async Task<T> GetASync<T>(IStorageFile file) where T : class
{
    try
    {    
        if (file != null)
        {
            IRandomAccessStream readStream = await file.OpenAsync(FileAccessMode.Read);
            IInputStream inputStream = readStream.GetInputStreamAt(0);                   
            using (XmlDictionaryReader reader = XmlDictionaryReader.CreateBinaryReader(inputStream.AsStream(), XmlDictionaryReaderQuotas.Max))
            {
                DataContractSerializer serializer = new DataContractSerializer(typeof(T));
                var entity = serializer.ReadObject(reader); //line A - here the problem 
                return entity as T;
            }                    
        }
        else
        {
            return null;
        }

    }
    catch (FileNotFoundException)
    {
        return null;
    }
    catch (Exception)
    {
        throw;
    }
}

Solution

  • Well, I have no idea why your code doesn't work. I'm suspecting a deadlock, but there shouldn't be one. :)

    However, I do have a couple performance recommendations that would probably avoid the problem as a side effect. The first is to use ConfigureAwait(false):

    IRandomAccessStream readStream = await file.OpenAsync(FileAccessMode.Read)
                                               .StartAsTask()
                                               .ConfigureAwait(false);
    

    The other is to read the file into memory (asynchronously) and then parse it. (I'm assuming from your code that you're storing one object per file).