asynchronous 相关问题

异步编程是用于推迟具有高延迟或低优先级的操作的策略,通常旨在提高软件的性能,响应性和/或可组合性。这些策略通常使用事件驱动编程和回调的某种组合来使用,并且可选地通过协同程序和/或线程来使用并发。

处理多个异步调用

我有一个包含 ID 等基本信息的书籍列表,我需要调用多个外部 API 端点来获取其余信息,例如图像、参考文献、作者简介等。 这是一种方法...

回答 3 投票 0

asyncio.sleep() 与 time.sleep()

当我进入 asyncio 页面时,第一个示例是一个 hello world 程序。当我在 python 3.73 上运行它时,我看不出与正常的有什么不同。谁能告诉我其中的区别并给出...

回答 3 投票 0

如何在 Blazor Server 启动时获取并缓存 IStringLocalizer 的数据?

我想使用Azure blob作为IStringLocalizer的资源文件,而不是本地存储的.resx文件。但是当我尝试在 IStringLocalizer 中获取数据时,有时数据不可用...

回答 0 投票 0

等待东京的两个期货之一

我有两个可以等待的未来。然而,我只想等待两个中的第一个完成,一旦发生就立即做其他事情。 有办法吗? 预先感谢!

回答 1 投票 0

Boost Asio 异步客户端

我正在尝试使用Boost asio编写一个异步客户端, 我写了下面的代码, #包括 #包括 #包括 我正在尝试使用 Boost asio 编写一个异步客户端, 我写了以下代码, #include <boost/asio.hpp> #include <boost/bind.hpp> #include <boost/asio/experimental/awaitable_operators.hpp> #include <boost/beast/http.hpp> #include <boost/json/src.hpp> namespace json = boost::json; namespace asio = boost::asio; namespace this_coro = asio::this_coro; using asio::ip::tcp; using boost::system::error_code; using namespace asio::experimental::awaitable_operators; #include <iostream> using namespace std; template <typename T> using Defer = asio::deferred_t::as_default_on_t<T>; using Socket = Defer<tcp::socket>; using Acceptor = Defer<tcp::acceptor>; using boost::asio::ip::tcp; class TCPClient { public: TCPClient(boost::asio::io_service& io_service, tcp::resolver::iterator endpoint_iterator) : io_service_(io_service), socket_(io_service) { connect(endpoint_iterator); } void write(const std::string& message) { io_service_.post(boost::bind(&TCPClient::do_write, this, message)); } void close() { io_service_.post(boost::bind(&TCPClient::do_close, this)); } private: void connect(tcp::resolver::iterator endpoint_iterator) { boost::asio::async_connect(socket_, endpoint_iterator, boost::bind(&TCPClient::handle_connect, this, boost::asio::placeholders::error)); } void handle_connect(const boost::system::error_code& error) { if (!error) { cout << "connected" << endl; write("Hello, World!"); read(); } else { cout << "connection failed" << endl; } } void do_write(const std::string& message) { boost::asio::async_write(socket_, boost::asio::buffer(message), boost::bind(&TCPClient::handle_write, this, boost::asio::placeholders::error)); } void handle_write(const boost::system::error_code& error) { if (!error) { cout << "write successfully" << endl; } else { cout << "write failed " << error << endl; } } void read() { socket_.async_read_some(boost::asio::buffer(data_, max_length), boost::bind(&TCPClient::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); //socket_.async_read_some(buf.prepare(1024), // boost::bind(&TCPClient::handle_read, this, // boost::asio::placeholders::error, // boost::asio::placeholders::bytes_transferred)); } void handle_read(const boost::system::error_code& error, size_t bytes_transferred) { if (!error) { std::cout << "Received: " << bytes_transferred << std::endl; read(); } else { // Handle the error std::cout << "read failed " << error << std::endl; } } void do_close() { socket_.close(); } boost::asio::io_service& io_service_; tcp::socket socket_; enum { max_length = 1024 }; char data_[max_length] = { 0 }; boost::asio::streambuf buf; }; int main() { boost::asio::io_service io_service; tcp::resolver resolver(io_service); tcp::resolver::iterator endpoint_iterator = resolver.resolve("localhost", "8989"); TCPClient client(io_service, endpoint_iterator); io_service.run(); while (1) {} return 0; } 客户端可以成功连接,并且正在调用处理程序。使用wireshark,我还可以看到 write() 函数发送“Hello, World”消息并收到回复,但写入或读取处理程序都没有被调用。 我尝试了不同的东西,看到了不同的示例代码,但我无法弄清楚。还尝试使用 coroutine 编写相同的代码,代码可以在下面找到,但是,我是异步套接字和 Boost Asio 的新手,我不确定我还在做什么(但正在努力实现) , #include <iostream> #include <boost/asio.hpp> #include <boost/asio/co_spawn.hpp> #include <boost/asio/detached.hpp> #include <boost/asio/use_awaitable.hpp> using boost::asio::ip::tcp; namespace asio = boost::asio; using asio::awaitable; using asio::co_spawn; using asio::detached; using asio::use_awaitable; awaitable<void> connectAndCommunicate() { try { asio::io_context io_context; tcp::socket socket(io_context); co_await socket.async_connect(tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 12345), use_awaitable); std::string message = "Hello, World!"; co_await asio::async_write(socket, asio::buffer(message), use_awaitable); char data[128]; std::size_t length = co_await socket.async_read_some(asio::buffer(data), use_awaitable); std::cout << "Received: " << std::string(data, length) << std::endl; } catch (const std::exception& e) { std::cerr << "Exception: " << e.what() << std::endl; } } int main() { asio::io_context io_context; co_spawn(io_context, connectAndCommunicate(), detached); io_context.run(); return 0; } 我希望更有经验的开发人员指出我的错误以及如何最好地做我想做的事情。 谢谢 第一版回顾 不要使用using命名空间 不要使用 boost::bind,当然也不要使用过时的 boost/bind.hpp include 不要包含大量不需要的标头,删除未使用的类型别名 使用您拥有的缩写命名空间 使用 io_context 代替已弃用的 io_service 不要传递对 io 上下文的引用;而是使用执行器 建议不要泄漏接口中的实现细节(将主机/端口作为构造函数参数,而不是某种特定类型的迭代器) 在链上时,不需要 post,因此在 handle_connect 中执行 do_write(),而不是 write() 现在我们的线路从 120 条减少到 69 条:Live On Coliru #include <boost/asio.hpp> #include <iostream> namespace asio = boost::asio; using namespace std::placeholders; using asio::ip::tcp; using boost::system::error_code; class TCPClient { public: TCPClient(asio::io_context& ioc, std::string const& host, std::string const& port) : socket_(ioc) { tcp::resolver resolver(ioc); connect(resolver.resolve(host, port)); } void write(std::string const& message) { post(socket_.get_executor(), std::bind(&TCPClient::do_write, this, message)); } void close() { post(socket_.get_executor(), std::bind(&TCPClient::do_close, this)); } private: void connect(tcp::resolver::iterator endpoint_iterator) { async_connect(socket_, endpoint_iterator, std::bind(&TCPClient::handle_connect, this, _1)); } void handle_connect(error_code ec) { if (!ec) { std::cout << "connected" << std::endl; do_write("Hello, World!"); read(); } else { std::cout << "connection failed (" << ec.message() << ")" << std::endl; } } void do_write(std::string const& message) { async_write(socket_, asio::buffer(message), std::bind(&TCPClient::handle_write, this, _1)); } void handle_write(error_code ec) { std::cout << "write " << ec.message() << std::endl; } void read() { socket_.async_read_some(asio::buffer(data_), std::bind(&TCPClient::handle_read, this, _1, _2)); // socket_.async_read_some(buf.prepare(1024), std::bind(&TCPClient::handle_read, this, _1, _2)); } void handle_read(error_code ec, size_t bytes_transferred) { std::cout << "Read " << ec.message() << " (" << bytes_transferred << ")" << std::endl; if (!ec) { std::cout << "Received: " << bytes_transferred << std::endl; read(); } else { // Handle the error } } void do_close() { socket_.close(); } tcp::socket socket_; std::array<char, 1024> data_{0}; // asio::streambuf buf; }; int main() { asio::io_context ioc; TCPClient client(ioc, "localhost", "8989"); ioc.run(); } 我可能无意中解决了一个我没有有意识提到的问题,但对我来说,它看起来只是有效(TM): 第二版审核 已经干净很多了!我建议 删除额外的io_context,你在一个协程中,根据定义有一个上下文。从this_coro获取执行者 使用deferred而不是use_awaitable来提高效率 不使用原始 C 数组 为了更接近第一个列表: 使用相同的缓冲区大小 还获取主机/端口信息并像第一个清单中那样解决它 循环读取 我们得到:在 Coliru 上生活 #include <boost/asio.hpp> #include <boost/asio/use_awaitable.hpp> #include <iostream> using boost::asio::ip::tcp; namespace asio = boost::asio; asio::awaitable<void> connectAndCommunicate(std::string host, std::string port) { try { auto ex = co_await asio::this_coro::executor; auto token = asio::deferred; tcp::socket s(ex); tcp::resolver resolver(ex); co_await async_connect(s, co_await resolver.async_resolve(host, port, token), token); std::string message = "Hello, World!"; co_await asio::async_write(s, asio::buffer(message), token); for (;;) { std::array<char, 1024> buf; auto length = co_await s.async_read_some(asio::buffer(buf), token); std::cout << "Received: " << quoted(std::string_view(buf.data(), length)) << std::endl; } } catch (boost::system::system_error const& se) { std::cerr << "Exception: " << se.code().message() << std::endl; } } int main() { asio::io_context ioc; co_spawn(ioc, connectAndCommunicate("127.0.0.1", "8989"), asio::detached); ioc.run(); } 我会考虑将 deferred 设置为默认执行器。讽刺的是,第一个代码清单定义了那些甚至不相关的类型别名:) Live On Coliru 未解之谜 事情被掩盖了,因为它们不是你问题的一部分: 链和输出消息队列(现在无论如何你都没有多个输出消息) 消息框架。如果您需要解释消息,async_read_some 是一个糟糕的方法。您将收到部分/串联的消息。这就是组合操作和动态缓冲区存在的原因。 错误处理。我稍微改进了它,但你需要意识到部分成功(特别是组合读取,但也许 async_read_some 可以返回字节 和 EOF 本身)

回答 1 投票 0

如何让异步方法返回值?

我知道如何创建异步方法,但说我有一个方法可以完成很多工作然后返回布尔值? 如何在回调中返回布尔值? 澄清: 公共 bool Foo()...

回答 7 投票 0

使用 pd.read_sql 和 asyncio 从数据库读取

我有三个表,每个表需要大约 1 分钟来查询(即总共 3 分钟),如下所示 从 my_utils 导入 get_engine 将 pandas 导入为 pd def main(): con1 = get_engine("表1&...

回答 2 投票 0

使用 Spring @Async 与直接使用 CompleteableFuture 相比有什么优势?

使用 Spring Async 与自己返回 CompletableFuture 相比有什么优势?

回答 3 投票 0

预期的“async”块,发现了不同的“async”块

我试图使用 futures::future::select_ok (游乐场): 使用 std::time::Duration; 使用东京; // 1.16.1 使用期货; // 0.3.19 #[东京::主要] 异步 fn main() { 让first_future = 异步{ ...

回答 2 投票 0

如何让长进程在后台运行而不中断UI

我正在尝试创建一个函数来创建 ItemObj,然后导入一些与其相关的请求。问题是它使用外部 API 来带来大量数据,这使得此步骤变慢。 我们

回答 1 投票 0

在React中创建打字机效果(使用JS)

我一直在尝试为我的网站创建打字机效果 - 目前动画可以工作,但每个字母出现两次(即我想让它说“欢迎!”但它打印出“

回答 1 投票 0

从RwLock访问T<Vec<RwLock<T>>>

我有一个应该在多个线程中传递的结构。它的结构如下: pub 结构状态{ 人类:RwLock>, 动物:RwLock 我有一个应该在多个线程中传递的结构。其结构如下: pub struct State{ humans: RwLock<Vec<RwLock<Human>>, animals: RwLock<Vec<RwLock<Animal>> } 这个想法是,如果线程只写入单个 Vec 元素,则不会锁定整个 Vec,而是只能读取相应的元素和所有其他元素。另一方面,当从 Vec 插入/删除时,它肯定会被完全锁定。 现在我还有一个函数,它返回一个特定的Human。为简单起见,它始终返回 N^2 元素。 impl State{ pub fn get_some_element(&self, N: usize) -> &Human{ // here i am a bit lost, because I run into temporary variables that cannot be passed, when unwrapping the LockGuards. } } 我的一个想法是使用tokio::sync::RwLockReadGuard::map: let humans = self.humans.read().await; RwLockReadGuard::map(humans, |f|{ &f.get(N^2) } 由于临时变量的存在,甚至无法返回(因此 LockGuard 到相应的元素)。 您能在这里帮助我并就如何有效解决该问题提供一些建议吗?谢谢你。 您无法从锁中获得简单的参考。即使在嵌套锁情况之外,这也不起作用: fn read_lock(lock: &std::sync::RwLock<i32>) -> &i32 { lock.read().unwrap() } 原因是read().unwrap()给你一个RwLockReadGuard。它看起来有点像共享引用,但事实并非如此。特别是,它是一个具有自己的析构函数的结构,该析构函数在执行时会释放锁。您无法通过 Rust 中的简单引用获得这种过期后行为。 另外,只是为了强调这一点:嵌套锁在这里没有什么区别。仍然必须执行“一些”代码来负责释放“每个”锁。只要看一下签名,我们就应该在返回类型中看到 RwLockReadGuard<RwLockReadGuard<Human>> 形式的内容。不幸的是,这似乎无法直接实现。 stdlib RwLock 没有任何 map 函数,并且 tokio 仅当您可以将内部内容作为简单引用获取时才有用,而不是作为受锁保护保护的另一件事(并且 async 也有点碍事)。因此,在这一点上,我建议要么将返回类型更改为泄漏更多数据结构的类型(例如返回锁而不是对内容的引用),如评论中所建议的;或者更改接口以使用闭包来处理获取的引用(类似于 with 上的 RefCell 方法及类似方法):fn with_element<F: FnOnce<&Human>>(&self, n: usize, f: F) { ... }

回答 1 投票 0

在Erlang中,发送到self是原子的吗?

据我所知,Erlang 进程总是会在其邮箱中接收第一条[到达]的消息,这些消息是与模式匹配的。我很好奇是否可以用它来获得以下假设:...

回答 1 投票 0

如何在PHP中使用ReactPHP获取并发

我想同时处理多个进程。我搜索并发现使用 ReactPHP 可以发生这种情况。我尝试过但没有成功。我添加了每个进程开始/结束时间的时间和

回答 1 投票 0

异步Python itertools链多个生成器

为了清晰起见更新了问题: 假设我有 2 个处理生成器函数: def gen1(): # 仅作为示例, yield 1 # 实际携带的收益率 yield 2 # 不同的计算权重 哎...

回答 3 投票 0

Boost asio async_read_some 并读取整个数据

我最近问了一个关于 Boost Asio 的问题,并从其中一位成员那里得到了一个有趣的建议 https://coliru.stacked-crooked.com/a/6e17518e3a3850f7。 它使用 async_read_until 并读取您...

回答 1 投票 0

为什么 CompletableFuture runAsync 在我的代码中不起作用?

我有示例代码,例如 私有布尔 exampleFunc(长 id) { 信息信息=新信息(); info.setCustomerId(100L); var res = CompletableFuture.runAsync(() -> exampleApi.doFunc(info)); 返回

回答 1 投票 0

Boost Beast async_write() 与队列

我有以下代码: std::queue< nlohmann::json > 传出消息; 无效会话::do_write( 无效 ) { if (outgoingMessages.size() > 0) { 自动消息=传出消息...

回答 2 投票 0

为什么异步文件写入比同步文件写入慢?

我目前正在尝试了解 asyncio 在 Python 中的工作原理。我想使用 aiofiles 库中的异步文件写入来加速文件写入。 我有一个同步写入功能: 定义

回答 1 投票 0

观看 Rust 中的频道

我需要帮助来理解borrow() 和borrow_and_update() 两者看起来都与我相似。 #[东京::主要] 异步 fn main() { 使用 tokio::sync::watch; 使用 tokio::time::{持续时间,睡眠}; 我...

回答 1 投票 0

© www.soinside.com 2019 - 2024. All rights reserved.