I am attempting to create a serialization interface (similar to Cocoa's NSCoding
protocol) so that I can get a quick binary representation of a class to send across a network or store in a database. However, some cases (especially involving image encoding) have many async-only methods that require await
ing. However, if the bytes do not get written in order then of course the whole representation is corrupted. I must make sure that the current object is finished serializing before I continue to the next object. Here is the main loop of what I am doing.
public async static Task<byte[]> Serialize(this IList<ISerializable> list) {
using (Archiver archiver = new Archiver()) {
archiver.Write(list.Count);
foreach (ISerializable value in list) {
await archiver.Write(value);
}
return archiver.Result;
}
}
Archiver
just uses MemoryStream
and BitmapWriter
under the hood to write either values that BinaryWriter
can accept directly, or ISerializable
objects, and then spits out the result as a byte array. ISerializable
is just an interface with two methods (Serialize
and Deserialize
). They both return Task
so that they can be await
ed. The problem is when I have a serialization method that doesn't have any async components. I can do one of two things:
A) I can tack on async
to that class's serialization methods anyway and put up with the compiler warning saying that it will execute synchronously (I don't like to have compiler warnings).
B) Manually return an empty task at the end of the method (return Task.Run(() => {});
). However, this looks and smells really weird.
Both A and B seem to execute without a problem, but are there any problems with this approach that I may have missed? I am not aware of a binary serializer in Windows Runtime (I included the tag just to dispel any confusion). Perhaps there is an option C that I can consider? Actually I didn't want to make the serialization methods async, but for some reason task.Wait()
was not waiting, and I was getting a null reference exception from trying to use an object created with CreateAsync
before it was ready.
EDIT I thought of an option C. I could just wrap the entire method in an await Task.Run(...)
call. Would this be normal?
I think the best solution here, assuming you want to execute the method synchronously is to write it normally, except you will return a completed Task
at the end of the method.
To get a completed Task
with some specific value, you can use Task.FromResult()
.
If you want a Task
with no value (i.e. actually just Task
, not Task<TResult>
), you can use for example Task.FromResult(true)
(which is a Task<bool>
) and implicitly cast it to Task
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With