asio use_future alih-alih hasil[ec]

Saya ingin membuat wadah masa depan, setiap masa depan adalah hasil tugas yang tidak berlaku sehingga saya dapat menggunakan wait_for_any pada wadah tersebut, setiap tugas adalah coroutine yang saat ini saya implementasikan menggunakan hasil_konteks, dan di dalam coroutine ini terdapat fungsi inisiasi yang mengembalikan ec dan hasil di mana saya menggunakan ec untuk menganalisis hasil. dan kemudian coroutine lain dipanggil melewati hasil_konteks yang sama.
saya ingin tahu cara membuat desain ini.
dan jika saya akan menggunakan use_future, bagaimana saya bisa meneruskan kode kesalahan agar ec tidak melempar kecuali tidak ada cara lain selain melemparkannya, dalam hal ini saya akan mencoba dan menangkap fungsi memulai async.
semua tugas ini akan diposting, muncul ... di asio io_service .
ini adalah bagian utama saya kode:
ini adalah asal mula tugas

boost::asio::spawn(GetServiceReference(), boost::bind(&HTTPRequest::Execute, boost::placeholders::_1, m_HttpClient_request_name, Get_mHTTPClient_Responses_Map()));

dan ini adalah coroutine yang menggunakan yield_context

void HTTPRequest::Execute(boost::asio::yield_context yield_r, std::string request_name, std::map<std::string, boost::shared_ptr<HTTPResponse>>& mHTTPClient_Responses_Map)
{
    resolver_iterator iterator_connect = boost::asio::async_connect(mSock, iterator_resolve, yield_r[ec]);
}

dan di dalam Execute kami menggunakan ec untuk menganalisis

if (ec == boost::system::errc::errc_t::success){}

dan di sini kita memulai coroutine lain dengan meneruskan konteks_hasil yang sama

SendRequest(yield_r);
}

saya ingin mengubahnya jadi saya memiliki wadah masa depan untuk semua Eksekusi yang dihasilkan, saya tidak peduli dengan hasil Eksekusi karena saya memasukkannya ke Respon kelas anggota.
Tapi saya memerlukan hasil di masa depan sehingga saya dapat menggunakan wait_any di wadah.


person ahmed allam    schedule 04.04.2020    source sumber


Jawaban (1)


Jika Anda dapat mengubah implementasi Anda, gunakan pola async_result.

Hal ini membuat Anda dapat menggunakan metode Anda dengan pendekatan apa pun (penanganan penyelesaian, konteks hasil, atau use_future).

Saya mereproduksi contoh mandiri dari di sini untuk mendapatkan inspirasi:

Demo Komprehensif

Menampilkan cara menggunakannya dengan

  • coro dan hasil[ec]
  • coro dan hasil + pengecualian
  • std::masa depan
  • penangan penyelesaian

Langsung di Coliru

#define BOOST_COROUTINES_NO_DEPRECATION_WARNING 
#include <iostream>
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/asio/use_future.hpp>

using boost::system::error_code;
namespace asio = boost::asio;

template <typename Token>
auto async_meaning_of_life(bool success, Token&& token)
{
#if BOOST_VERSION >= 106600
    using result_type = typename asio::async_result<std::decay_t<Token>, void(error_code, int)>;
    typename result_type::completion_handler_type handler(std::forward<Token>(token));

    result_type result(handler);
#else
    typename asio::handler_type<Token, void(error_code, int)>::type
                 handler(std::forward<Token>(token));

    asio::async_result<decltype (handler)> result (handler);
#endif

    if (success)
        handler(error_code{}, 42);
    else
        handler(asio::error::operation_aborted, 0);

    return result.get ();
}

void using_yield_ec(asio::yield_context yield) {
    for (bool success : { true, false }) {
        boost::system::error_code ec;
        auto answer = async_meaning_of_life(success, yield[ec]);
        std::cout << __FUNCTION__ << ": Result: " << ec.message() << "\n";
        std::cout << __FUNCTION__ << ": Answer: " << answer << "\n";
    }
}

void using_yield_catch(asio::yield_context yield) {
    for (bool success : { true, false }) 
    try {
        auto answer = async_meaning_of_life(success, yield);
        std::cout << __FUNCTION__ << ": Answer: " << answer << "\n";
    } catch(boost::system::system_error const& e) {
        std::cout << __FUNCTION__ << ": Caught: " << e.code().message() << "\n";
    }
}

void using_future() {
    for (bool success : { true, false }) 
    try {
        auto answer = async_meaning_of_life(success, asio::use_future);
        std::cout << __FUNCTION__ << ": Answer: " << answer.get() << "\n";
    } catch(boost::system::system_error const& e) {
        std::cout << __FUNCTION__ << ": Caught: " << e.code().message() << "\n";
    }
}

void using_handler() {
    for (bool success : { true, false })
        async_meaning_of_life(success, [](error_code ec, int answer) {
            std::cout << "using_handler: Result: " << ec.message() << "\n";
            std::cout << "using_handler: Answer: " << answer << "\n";
        });
}

int main() {
    asio::io_service svc;

    spawn(svc, using_yield_ec);
    spawn(svc, using_yield_catch);
    std::thread work([] {
            using_future();
            using_handler();
        });

    svc.run();
    work.join();
}

Cetakan:

using_yield_ec: Result: Success
using_yield_ec: Answer: 42
using_yield_ec: Result: Operation canceled
using_yield_ec: Answer: 0
using_future: Answer: 42
using_yield_catch: Answer: 42
using_yield_catch: Caught: Operation canceled
using_future: Caught: Operation canceled
using_handler: Result: Success
using_handler: Answer: 42
using_handler: Result: Operation canceled
using_handler: Answer: 0

Catatan: untuk mempermudah saya belum menambahkan sinkronisasi keluaran, sehingga keluaran dapat bercampur tergantung pada urutan eksekusi runtime

person sehe    schedule 05.04.2020
comment
Saya mempelajari jawaban Anda selama pencarian saya dan itu sudah di-bookmark, tetapi saya merasa kesulitan memahami apa yang sebenarnya terjadi ketika token penyelesaian dikonversi ke handler. Semua contoh berbicara tentang penggunaan tanda tangan untuk membentuk tipe handler. Tetapi handler yang dibentuk hanyalah prototipe. tidak ada isi untuk handler.jadi apa yang akan dipanggil ketika operasi async selesai????.mengenai pertanyaan saya saat ini saya masih bingung tentang urutan operasinya.misalnya: saya akan membuat tugas-tugas yang dikemas kemudian menambahkannya ke wadah. ..TAPI apakah saya meluncurkan ios.run dari thread yang sama atau berbeda? - person ahmed allam; 05.04.2020
comment
menyelesaikan komentar:dan ke mana saya harus menelepon:wait_for_any???di thread yang sama tempat saya membuat tugas ATAU setelah ios.run di thread yang sama atau berbeda??? - person ahmed allam; 05.04.2020
comment
sekarang saya rasa saya mengerti apa yang dimaksud dengan handler...itu hanya penentuan tipe. dan ada beberapa kasus menurut saya ini disebut sifat tipe yang menentukan pada waktu kompilasi jenis handler apa yang diteruskan dan menurut ini mereka meneruskan argumen tanda tangan ke tipe atau bagian argumen yang ditentukan seperti dalam kasus masa depan...Jadi yang akan dipanggil adalah argumen yang diteruskan dari pengguna jika itu adalah fungsi objeklambda,bind,callback,penunjuk fungsi atau itu adalah mekanisme pembuatan masa depan dalam kasus use_future , atau hanya mengganti konteks jika ada coroutine yang dipertaruhkan atau tidak ada yang dipertaruhkan ››› - person ahmed allam; 17.04.2020
comment
coroutine jika pemindahan (coro) dilewati. apakah benar????sekarang bagaimana kita bisa menggunakan token penyelesaian yang berbeda ini dengan spawn ,post???dapatkah kita menghindari pembuatan async_function dan menggunakan packaged_task untuk mengonversi fungsi menjadi tugas yang kembali di masa mendatang? ??apakah tugas yang dihasilkan sama dengan async_function yang dibuat??akankah kita menggunakan async_function dengan tugas yang dikemas ATAU menggunakan_future?? - person ahmed allam; 17.04.2020
comment
Saya memberi suara positif pada komentar yang menurut saya saya pahami dan masuk akal. Saya tidak mengerti apa yang Anda maksud dengan semua pertanyaan itu (???) - person sehe; 18.04.2020
comment
ketika saya mencoba menggunakan fungsi dalam kode saya, sejauh yang saya tahu saya memiliki 2 opsi, yang pertama adalah menghindari membuat fungsi tersusun secara langsung dan mencoba menggunakan packaged_task untuk membuat tugas dari fungsi saya dan kemudian memposting tugas ini›› ›ini menyebabkan beberapa kesalahan yang menghentikan kemajuan saya dan saya membuat stackoverflow.com/questions/61181774/ untuk mencari bantuan tentangnya. ATAU opsi kedua adalah membaca tentang fungsi tersusun dan model universal yang sangat menarik tetapi lebih rumit dan itu memiliki beberapa kebutuhan untuk mengetahui subjek seperti ciri-ciri tipe dan - person ahmed allam; 18.04.2020
comment
penerusan sempurna yang mengarah ke referensi universal dan SFINAE serta alias templat dan makro yang sangat menarik dan saya senang telah membacanya, saya selalu berusaha menghindari subjek yang sulit ini. Jadi sekarang saya mencoba membuat fungsi tersusun tetapi bertanya-tanya mengapa saya mengalami kesalahan dengan pendekatan pertama saya menggunakan packaged_task dengan post. Jadi saya kira spawn hanya digunakan dengan operasi tersusun menggunakan hasil sebagai token penyelesaian? apakah ini benar?...dan packaged_task hanya digunakan dengan utas dan tidak dapat digunakan dengan postyang memerlukan penyalinan tugas dan tugas hanya bergerak,??apakah ini benar?? - person ahmed allam; 18.04.2020
comment
dan selama ini saya menghadapi pertanyaan: apakah fungsi dikonversi ke tugas menggunakan tugas yang dikemas SETARA dengan fungsi yang dibuat secara asinkron menggunakan use_future??terima kasih atas balasan Anda - person ahmed allam; 18.04.2020
comment
saya membuat beberapa tambahan pada kode contoh Anda untuk mencoba memahami fungsi komposisi async. saya menambahkan:boost::asio::steady_timer t(svc, boost::asio::chrono::seconds(45)); t.async_wait(&cetak); jawaban otomatis = async_meaning_of_life(true, asio::use_future); std::cout ‹‹ FUNGSI ‹‹ : Jawaban: ‹‹ jawaban.get() ‹‹ \n; - person ahmed allam; 18.04.2020
comment
Bisakah Anda memposting pertanyaan baru? Secara umum, packaged_task tidak setara, terutama karena menghapus tipe handler sebenarnya. Jenis penangan mencakup informasi seperti kapan untaian digunakan. Dengan menghapus tipe dengan packaged_task, ASIO kehilangan tipe handler sebenarnya dan tidak dapat mempertahankan semantiknya. - person sehe; 18.04.2020
comment
saya membuat pertanyaan ini 5 hari yang lalu. stackoverflow .com/questions/61181774/. ini terutama tentang masalah awal saya. Tetapi saya menemukan bahwa saya kurang memahami beberapa hal utama yang saya coba dapatkan. Saya mencoba beberapa kasus berbeda dengan kode Anda. Saya akan mempostingnya setelah selesai. Saya akan menerima jawaban Anda sekarang dan lanjutkan dengan modifikasi di pertanyaan berikutnya - person ahmed allam; 18.04.2020
comment
dan ini adalah pertanyaan lain dengan modifikasi pada kode Anda untuk menunjukkan poin-poin tidak jelas dan pertanyaan saya stackoverflow.com/questions/61329157/ - person ahmed allam; 20.04.2020