Good day. I have a collection of some objects.

When I run the application, I need to load data from the file into the collection.

Deserialization is our everything, but I have a problem with an asynchronous file request.

How can I upload a file in this style?

History = LoadFile ("History.xml");

static async void LoadObject(StorageFile Path) { using (var readerStream = await Path.OpenStreamForReadAsync()) { var Serializer = new XmlSerializer(typeof(?????); try { ????? = (??????)Serializer.Deserialize(readerStream); } catch (Exception e) { ShowMessage(string.Format("Exception: {0}\n{1}", e.InnerException, e.Message)); } } } 

Approximately in this way I have an organized loading method.

  • The question is what? - andreycha

1 answer 1

For starters, you cannot deserialize an unknown data type. Moreover, you need to return some type from a method. So let's make the method generalized, after that it’s immediately clear what type of serializer to use:

 static async Task<T> LoadObject<T>(StorageFile path) { using (var readerStream = await path.OpenStreamForReadAsync()) { var serializer = new XmlSerializer(typeof(T)); try { return (T)serializer.Deserialize(readerStream); } catch (Exception e) { //ShowMessage(string.Format("Exception: {0}\n{1}", e.InnerException, e.Message)); throw new DeserializationFailedException("Cannot deserialize", e); } } } 

The type when calling a function must be specified, of course, the same as you specified during serialization .

Changes:

  • Separate content from presentation. Deserialization functions do not need to display messages in the UI
  • We have a return type, in case of an error, we throw a custom exception. Outer code, yes, you need to catch it. The suppression of errors was still wrong, the application does not have the right to be anyway, whether an error occurred.
  • Local variables are usually called with a lowercase letter.

If the load is too slow (for example, the file is too large), you can unload the deserialization into a separate stream:

 return await Task.Run(() => (T)serializer.Deserialize(readerStream)); 
  • Did you describe the method signature correctly? Maybe this way? static async Task<T> LoadObject<T>(StorageFile path) - bodynar
  • @bodynar: Exactly, corrected the answer - VladD
  • I blunted something a little - how to use this method? I initially assumed that there would be a method to which I would send a StorageFile and in return I would receive a deserialized object. History = LoadObject<MyHistory>(Path); In this style. - bodynar
  • Just never worked with Task before - bodynar
  • @bodynar: Well, you have the same async method, so through await: History = await LoadObject<MyHistory>(Path) . - VladD