How can I handle an interface method that may or may not be asynchronous?

I am trying to create a serialization interface (similar to Cocoa's NSCoding protocol) in order to get a quick binary representation of a class to send over the network or save to the database. However, in some cases (especially using image encoding), there are many asynchronous methods that require await ing. However, if the bytes are not written in order, then, of course, the whole representation is corrupted. I have to make sure that the current object has finished serializing before I move on to the next object. Here is the main loop of what I'm 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 simply uses a MemoryStream and a BitmapWriter under the hood to write values ​​that a BinaryWriter can accept directly, or ISerializable objects, and then spit the result out as an array of bytes. 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 that I have a serialization method that does not have any asynchronous components. I can do one of two things:

A) In any case, I can apply the async method to these serialization methods of this class and come up with a compiler warning saying that it will execute synchronously (I don't want to have a compiler warning).

B) Manually return an empty task at the end of the method ( return Task.Run(() => {}); ). However, it looks and smells very strange.

Both A and B seem to complete without problems, but are there any problems with this approach that I may have missed? I don't know about the binary serializer in Windows Runtime (I included a tag to dispel any confusion). Perhaps there is option C that I can consider? Actually, I didn’t want to use async serialization methods, but for some reason task.Wait() didn’t expect it, and I got a reference link exception from trying to use an object created using CreateAsync before it was ready.

EDIT I was thinking about option C. I could just wrap the whole method in an await Task.Run(...) call. Will it be okay?

+7
source share
1 answer

I think the best solution here, assuming that you want to execute the method synchronously, is to write it normally, except that you will return the completed Task at the end of the method.

To get a completed Task with a specific value, you can use Task.FromResult() .

If you want Task without a value (i.e. actually just Task , not Task<TResult> ), you can use, for example, Task.FromResult(true) (which is Task<bool> ) and implicitly drop it to Task

+4
source

All Articles