Projetando interfaces e assíncronas


9

Suponha que eu criei uma interface IFolderRepositorycom métodos assim:

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

e eu implementei DatabaseFolderRepositorye vamos dizer CacheFolderRepositoryDecorator. Agora, 'centenas de linhas depois', gostaria de adicionar a funcionalidade das pastas do SkyDrive para estar pronto para adicionar SkyDriveFolderRepository. Infelizmente, enquanto a DatabaseFolderRepositoryimplementação usou métodos síncronos para conversar com o banco de dados, o skydrive usa muitos asynce await. O que fazer nesse caso? No caso de métodos nulos marcando-o como assíncrono, não é uma solução (é necessário um tratamento de exceção). Devo alterar a interface para retornar Task<T>? Claro que funcionará no exemplo acima, mas são apenas duas classes de implementação de interface. Ou a maioria das minhas interfaces deve ter Tasktipos de retorno (contra você não vai precisar disso)?


Não relacionado à sua pergunta (desculpe), mas se você tem uma IFolderinterface, por que você confia na implementação concreta ( Folder) em todos os seus métodos?
Konrad Morawski

11
O que seu chamador espera? A API que você implementa é baseada em códigos de erro, exceções, retornos de chamada ou o quê? Você pode mudar isso?
David.pfx

@KonradMorawski foi erro de digitação - desculpe. É baseado em exceções e não posso alterá-lo.
fex

Respostas:


10

Você provavelmente encontrará este artigo do MSDN sobre práticas assíncronas como uma boa leitura.

Você perguntou:

Infelizmente, enquanto a DatabaseFolderRepositoryimplementação usou métodos síncronos para conversar com o banco de dados, o skydrive usa muitos asynce await.

É aqui que a subseção do artigo Async All the Waydo MSDN que vinculei será pertinente à sua situação.

Em particular, geralmente é uma má idéia bloquear o código assíncrono chamando Task.Wait ou Task.Result. Esse é um problema especialmente comum para programadores que estão “mergulhando os pés” em programação assíncrona, convertendo apenas uma pequena parte de seu aplicativo e envolvendo-o em uma API síncrona, para que o restante do aplicativo fique isolado das alterações. Infelizmente, eles têm problemas com impasses.

Como você possui pelo menos uma interface que precisa ser assíncrona, o YAGNI é revertido. Você está indo precisar de fazer alterações para que suas interfaces são consistentes. Sim, isso criará mais esforço antecipadamente para você. Mas o benefício é menos risco de impasse; depuração menos complexa; e bloqueio mais previsível (quando realmente precisa ocorrer).

Estou ignorando algumas das outras perguntas que você fez, pois acho que abordei o núcleo da sua pergunta. Lide com o núcleo e as demais perguntas desaparecem. O artigo é bastante envolvido e aborda os outros pontos que você mencionou, além de apontar armadilhas adicionais.

A programação assíncrona é uma daquelas em que você precisa abraçar todo o conceito e apenas seguir em frente. Tentar apenas "mergulhar os dedos dos pés" em uma base fragmentada acaba sendo muito mais complicado do que simplesmente pular direto.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.