panggilan perpustakaan async saling mengandalkan dan bagaimana cara menanganinya?

ini adalah lanjutan dari pertanyaan sebelumnya yang saya posting Memanggil metode async menggunakan Task.Run sepertinya salah?

Saya pikir kode yang ditulis oleh kontraktor salah tetapi mengikuti jawaban yang diberikan, saya sekarang bertanya-tanya apakah itu kesalahan perpustakaan. Perpustakaan ini memaparkan dua metode yang perlu saya gunakan. Yang satu mengembalikan "templat" dan yang lain menggunakan sebagian dari templat ini (tetap demikian dalam implementasi saya). Namun keduanya adalah metode async yang mengembalikan Tasks.

Untuk menjelaskan perpustakaan saya memiliki metode:

public Task<TemplateInfo> TemplateInfo(TemplateInfoRequest request);
public Task<List<EmailResult>> SendMessageTemplate(SendMessageTemplateRequest request);

Saya perlu menyebutnya sebagai berikut:

public bool SendMessage()
{
  var template = TemplateInfo(...);
  var message = //use template to create message
  var sendResponse = SendMessageTemplate(message);

   return sendResponse.Count > 0;
}

Jadi panggilan kedua bergantung pada panggilan pertama. Di sinilah async tidak masuk akal bagi saya. Saya tidak bisa dan tidak ingin menjalankannya secara paralel. Saya ingin menjalankannya secara berurutan. Saya ingin metode saya sinkron.

jawaban di pertanyaan saya sebelumnya juga menyatakan:

Karena Anda memblokir metode asinkron (yang tidak boleh Anda lakukan), ada kemungkinan Anda akan menemui jalan buntu.

Jadi bagaimana cara mengakses metode async ini sedemikian rupa sehingga diproses secara bergantian dan mengembalikan hasil yang sinkron tetapi tidak menyebabkan kebuntuan?


person Liam    schedule 16.09.2015    source sumber
comment
Liam kamu sangat sangat sangat bingung. Async tidak berarti bersamaan.   -  person Aron    schedule 16.09.2015
comment
@Aron: Asynchrony adalah salah satu bentuk konkurensi. Namun, asinkroni tidak sama dengan paralelisme.   -  person Stephen Cleary    schedule 17.09.2015


Jawaban (1)


Async tidak (tentu saja) berarti paralel.

Anda dapat memanggil kedua metode async berurutan tanpa keduanya berjalan secara paralel. Cukup panggil tugas pertama dan tunggu tugas yang dikembalikan, lalu lakukan hal yang sama dengan tugas kedua.

var template = await TemplateInfo(...);
var message = //use template to create message
var sendResponse = await SendMessageTemplate(message);

Ini masih berguna dibandingkan dengan kode sinkron karena ketika operasi asinkron "berjalan" tidak diperlukan thread sehingga thread Anda dapat berfungsi di bagian lain aplikasi Anda.

Jika Anda memanggil keduanya dan hanya menunggu tugas yang dikembalikan, Anda (mungkin) akan menjalankannya secara paralel:

var templateTask = TemplateInfo(...);
var sendResponseTask = SendMessageTemplate(message);
await templateTask;
await sendResponseTask;
person i3arnon    schedule 16.09.2015
comment
Saya sarankan Anda menambahkan sedikit tentang I/O asinkron non-pemblokiran untuk memperjelas keuntungan dari asinkron berurutan. - person Aron; 16.09.2015
comment
Tetapi untuk menambahkan await, saya kemudian harus menandai metode saya sebagai async dan mengembalikan Task, saya hanya ingin satu nilai, secara sinkron. Saya hanya akan menggunakan .Result tapi kemudian saya memblokir secara async bukan? Hal yang menurutku tidak seharusnya aku lakukan. Saya telah menambahkan detail dalam pertanyaan itu. - person Liam; 16.09.2015
comment
Saya kira saya bingung, pada titik tertentu saya harus berhenti memanggil metode async dan agar sinkron. Atau bagaimana cara memberi tahu pengguna apa yang terjadi. Jadi bagaimana saya bisa keluar dari sini dengan anggun tanpa menghalangi - person Liam; 16.09.2015
comment
@Liam Pilihan terbaik adalah async sepenuhnya. Hal ini memerlukan perubahan pemanggilan metode hingga Anda mencapai puncak (yang dapat berupa pengendali peristiwa, Main, dan seterusnya). Jika Anda tidak dapat melakukannya karena alasan tertentu maka opsi selanjutnya adalah tidak menggunakan async sama sekali dan memiliki kode sinkron sepenuhnya. Jika itu bukan pilihan (karena Anda menggunakan perpustakaan yang hanya memiliki API async) maka Anda tidak memiliki pilihan apa pun selain memblokir kode async dan kemudian mencoba memastikannya dilakukan dengan aman. - person i3arnon; 16.09.2015