【问题标题】:Proper way to implement async function in Qt/DBus adaptor在 Qt/DBus 适配器中实现异步功能的正确方法
【发布时间】:2016-12-17 16:23:05
【问题描述】:

如 D-Bus 文档中所述,所有 IPC 调用都被视为异步调用。当 Qt 通过 QDBusAbstractInterface 调用远程 D-Bus 对象时,会有完全异步的 QBusPendingCall 并在调用完成时提供信号。

在我的应用程序设计中,我想在我的对象适配器上实现异步调用,但当前的 Qt/DBus 实现假定所有方法调用都是阻塞的。

那么,有一个问题:有没有合适的方法来实现异步处理 D-Bus 方法调用?

【问题讨论】:

  • 如果您展示了一种实际阻止方法的示例,则此问题更有可能得到答案。现在至少对我来说有点不清楚(然后我还没有使用过 dbus,真的)。

标签: c++ qt c++11 asynchronous qdbus


【解决方案1】:

Declaring Slots in D-Bus Adaptors 对此进行了很好的解释。

为此,我们编写了一个槽,将请求数据存储在一个持久结构中,使用QDBusMessage::setDelayedReply(true) 向调用者指示将稍后发送响应。

struct RequestData
{
    QString request;
    QString processedData;
    QDBusMessage reply;
};

QString processRequest(const QString &request, const QDBusMessage &message)
{
    RequestData *data = new RequestData;
    data->request = request;
    message.setDelayedReply(true);
    data->reply = message.createReply();
    QDBusConnection::sessionBus().send(data->reply);

    appendRequest(data);
    return QString();
}

需要使用QDBusConnection::sessionBus().send(data->reply) 来明确通知调用者响应将被延迟。在这种情况下,返回值并不重要;我们返回一个任意值以满足编译器的要求。

当请求被处理并且回复可用时,它应该使用获得的QDBusMessage对象发送。在我们的示例中,回复代码可能如下所示:

void sendReply(RequestData *data)
{
    // data->processedData has been initialized with the request's reply
    QDBusMessage &reply = &data->reply;

    // send the reply over D-Bus:
    reply << data->processedData;
    QDBusConnection::sessionBus().send(reply);

    // dispose of the transaction data
    delete data;
}

从示例中可以看出,当延迟回复到位时,来自槽的返回值将被 Qt D-Bus 忽略。它们仅用于在将适配器的描述传达给远程应用程序时确定插槽的签名,或者在插槽中的代码决定不使用延迟回复的情况下。

通过在原始消息上调用 QDBusMessage::reply() 从 Qt D-Bus 请求延迟回复本身。然后,被调用代码负责最终向调用者发送回复。

警告:当调用者发出方法调用并等待回复时,它只会等待有限的时间。打算花费很长时间才能完成的插槽应在文档中明确说明这一事实,以便调用者正确设置更高的超时时间。

【讨论】:

  • 虽然理论上这可以回答这个问题,it would be preferable 在这里包含答案的基本部分,并提供链接以供参考。
猜你喜欢
  • 2011-01-09
  • 2021-07-10
  • 1970-01-01
  • 2015-05-31
  • 1970-01-01
  • 2013-08-30
  • 1970-01-01
  • 2021-02-13
  • 1970-01-01
相关资源
最近更新 更多