Diseño de interfaces y asíncronos

9

Supongamos que he creado una interfaz IFolderRepositorycon métodos como ese:

IEnumerable<Folder> GetAllFolders();
Folder GetFolderWithId(int id);
void AddFolder(Folder newFolder);
void ModifyFolder(Folder folderToModify, Folder folderAfterModification);
void RemoveFolder(Folder folderToRemove);

y lo he implementado DatabaseFolderRepositoryy digamos CacheFolderRepositoryDecorator. Ahora 'cientos de líneas después' me gustaría agregar funcionalidades de carpetas SkyDrive, así que estoy listo para agregar SkyDriveFolderRepository. Desafortunadamente, mientras que la DatabaseFolderRepositoryimplementación usó métodos sincrónicos para hablar con la base de datos, skydrive one usa mucho asyncy await. ¿Qué hacer en tal caso? En el caso de los métodos nulos, marcarlo como asíncrono no es una solución (necesita un manejo excepcional). ¿Debo cambiar la interfaz para volver Task<T>? Claro que funcionará en el ejemplo anterior, pero son solo 2 clases de implementación de interfaz. ¿O debería la mayoría de mis interfaces tener Tasktipos de retorno (en contra de usted no va a necesitar que la regla)?

fex
fuente
Sin relación con su pregunta (lo siento), pero si tiene una IFolderinterfaz, ¿por qué confía en la implementación concreta ( Folder) en todos sus métodos?
Konrad Morawski
1
¿Qué espera tu interlocutor? ¿La API que implementa se basa en códigos de error, excepciones, devoluciones de llamada o qué? ¿Puedes cambiarlo?
david.pfx
@KonradMorawski fue un error tipográfico, lo siento. Se basa en excepciones y no puedo cambiarlo.
fex

Respuestas:

10

Probablemente encontrará que este artículo de MSDN sobre prácticas asincrónicas es una buena lectura.

Tu preguntaste:

Desafortunadamente, mientras que la DatabaseFolderRepositoryimplementación usó métodos sincrónicos para hablar con la base de datos, skydrive one usa mucho asyncy await.

Aquí es donde la subsección Async All the Wayen el artículo de MSDN que vinculé será pertinente a su situación.

En particular, generalmente es una mala idea bloquear el código asincrónico llamando a Task.Wait o Task.Result. Este es un problema especialmente común para los programadores que están "sumergiendo los dedos de los pies" en programación asincrónica, convirtiendo solo una pequeña parte de su aplicación y envolviéndola en una API síncrona para que el resto de la aplicación esté aislada de los cambios. Desafortunadamente, se topan con problemas con puntos muertos.

Como tiene al menos una interfaz que debe ser asíncrona, YAGNI se invierte. Usted está a tener que hacer cambios para que sus interfaces son compatibles. Sí, creará más esfuerzo por adelantado para usted. Pero el beneficio es menos riesgo de punto muerto; depuración menos compleja; y un bloqueo más predecible (cuando realmente necesita ocurrir).

Me estoy saltando algunas de las otras preguntas que hizo, ya que creo que abordé el núcleo de su pregunta. Trate con el núcleo y el resto de sus preguntas desaparecerán. El artículo está bastante involucrado y aborda los otros puntos que mencionó, además de señalar dificultades adicionales.

La programación asincrónica es una de esas en las que tienes que abrazar todo el concepto y seguirlo. Tratar de "sumergir los dedos de los pies" poco a poco termina siendo mucho más complicado que simplemente saltar directamente.


fuente