Merancang antarmuka dan async

9

Misalkan saya telah membuat antarmuka IFolderRepositorydengan metode seperti itu:

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

dan saya sudah menerapkan DatabaseFolderRepositorydan katakanlah CacheFolderRepositoryDecorator. Sekarang 'ratusan baris kemudian' Saya ingin menambahkan fungsi folder SkyDrive jadi saya siap untuk menambahkan SkyDriveFolderRepository. Sayangnya sementara DatabaseFolderRepositoryimplementasi menggunakan metode sinkron untuk berbicara dengan database, skydrive satu menggunakan banyak asyncdan await. Apa yang harus dilakukan dalam kasus seperti itu? Dalam kasus metode void menandainya async bukanlah solusi (perlu penanganan pengecualian). Haruskah saya mengubah antarmuka untuk kembali Task<T>? Tentu itu akan bekerja dalam contoh di atas tetapi mereka hanya 2 kelas implementasi antarmuka. Atau haruskah sebagian besar antarmuka saya memiliki Tasktipe pengembalian (terhadap Anda tidak akan memerlukannya aturan)?

fex
sumber
Tidak terkait dengan pertanyaan Anda (maaf), tetapi jika Anda memiliki IFolderantarmuka, mengapa Anda mengandalkan implementasi konkret ( Folder) dalam semua metode Anda?
Konrad Morawski
1
Apa yang diharapkan oleh penelepon Anda? Apakah API yang Anda terapkan berdasarkan kode kesalahan, pengecualian, panggilan balik atau apa? Bisakah Anda mengubahnya?
david.pfx
@KonradMorawski itu salah ketik - maaf. Itu didasarkan pada pengecualian dan saya tidak bisa mengubahnya.
fex

Jawaban:

10

Anda mungkin akan menemukan artikel MSDN ini tentang praktik Asynchronous sebagai bacaan yang baik.

Kamu bertanya:

Sayangnya sementara DatabaseFolderRepositoryimplementasi menggunakan metode sinkron untuk berbicara dengan database, skydrive satu menggunakan banyak asyncdan await.

Di sinilah sub-bagian Async All the Waydalam artikel MSDN yang saya tautkan terkait dengan situasi Anda.

Secara khusus, biasanya ide yang buruk untuk memblokir kode async dengan memanggil Task.Wait atau Task.Result. Ini adalah masalah yang sangat umum bagi programmer yang "mencelupkan jari kaki" ke dalam pemrograman asinkron, hanya mengonversi sebagian kecil dari aplikasi mereka dan membungkusnya dalam API yang sinkron sehingga sisa aplikasi terisolasi dari perubahan. Sayangnya, mereka mengalami masalah dengan kebuntuan.

Karena Anda memiliki setidaknya satu antarmuka yang perlu disinkronkan, YAGNI dibalik. Anda yang akan perlu untuk melakukan perubahan sehingga antarmuka Anda konsisten. Ya, itu akan menciptakan lebih banyak upaya di depan untuk Anda. Tetapi manfaatnya adalah risiko kebuntuan yang lebih sedikit; debugging yang kurang rumit; dan lebih banyak pemblokiran yang dapat diprediksi (saat itu sebenarnya perlu terjadi).

Saya melewatkan beberapa pertanyaan lain yang Anda tanyakan karena saya pikir saya menjawab inti dari pertanyaan Anda. Berurusan dengan inti dan sisa pertanyaan Anda hilang. Artikel ini cukup terlibat dan membahas poin-poin lain yang Anda kemukakan serta menunjukkan perangkap tambahan.

Pemrograman asinkron adalah salah satu di mana Anda harus merangkul seluruh konsep dan hanya pergi dengannya. Mencoba untuk hanya "mencelupkan jari kaki ke dalam" sedikit demi sedikit berakhir menjadi jauh lebih rumit daripada hanya melompat langsung.


sumber