Próbuję utworzyć interfejs serializacji (podobny do protokołu Cocoa o numerze NSCoding
), aby uzyskać szybką binarną reprezentację klasy, która będzie wysyłana przez sieć lub sklep w bazie danych. Jednak niektóre przypadki (szczególnie związane z kodowaniem obrazu) mają wiele metod asynchronicznych, które wymagają zastosowania. Jeśli jednak bajty nie zostaną zapisane w kolejności, to oczywiście cała reprezentacja jest uszkodzona. Muszę się upewnić, że bieżący obiekt jest gotowy do serializacji, zanim przejdę do następnego obiektu. Oto główna pętla tego, co robię.Jak mogę obsłużyć metodę interfejsu, która może być lub może nie być asynchroniczna?
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
prostu wykorzystuje MemoryStream
i BitmapWriter
pod maską napisać albo wartości, które BinaryWriter
może przyjąć bezpośrednio lub ISerializable
obiekty, a następnie wypluwa wynik w postaci tablicy bajtów. ISerializable
to tylko interfejs z dwiema metodami (Serialize
i Deserialize
). Oba zwracają numer Task
, dzięki czemu mogą być edytowane pod numerem await
. Problem polega na tym, że mam metodę serializacji, która nie zawiera żadnych komponentów asynchronicznych. Mogę wykonać jedną z dwóch rzeczy:
A) Mogę jednak przylepić się do async
do metod serializacji tej klasy i na wszelki wypadek z ostrzeżeniem kompilatora, że będzie wykonywał się synchronicznie (nie lubię ostrzeżeń kompilatora).
B) Ręcznie zwróć puste zadanie na końcu metody (return Task.Run(() => {});
). Jednak wygląda i pachnie naprawdę dziwnie.
Zarówno A, jak i B wydają się wykonywać bez problemu, ale czy są jakieś problemy z tym podejściem, które mogłem przegapić? Nie wiem o serializatorze binarnym w środowisku wykonawczym systemu Windows (dodałem tag tylko po to, aby rozwiać wszelkie wątpliwości). Być może jest opcja C, którą mogę rozważyć? Właściwie nie chciałem, aby metody serializacji asynchronizowały się, ale z jakiegoś powodu task.Wait()
nie czekał, a ja otrzymywałem zerowy wyjątek odniesienia, próbując użyć obiektu utworzonego z CreateAsync
, zanim był gotowy.
EDIT Pomyślałem o opcji C. Mogłem po prostu zawinąć całą metodę w rozmowie await Task.Run(...)
. Czy to byłoby normalne?
Możesz czekać na Task.Delay (0), natychmiast powróci. –
@HansPassant Raczej podoba mi się to rozwiązanie ^^ – borrrden
Czy Twój obraz przetwarza bibliotekę innej firmy? Pytam, ponieważ wydaje mi się, że kodowanie obrazu (i ogólnie serializacja) nie są naturalnie operacjami "asynchronicznymi". Powiedział, że wolę rozwiązanie @ svick, które jest jak opcja B z mniejszym obciążeniem. –