d设计事件循环
原文
结构化并发库具有严格的任务所有权概念.
或用D现有的析构器规则
异步api,最好地复制窗口API.可回调和同步.这里
我在arsd.http2中使用了类似模型,调用返回请求函数,可附加回调等,然后发送它,然后在需要时等待响应对象.我非常喜欢它,即使没有完整事件循环,也可用它,它只是根据需要一步步地执行事件循环.
我想扩展它到其他函数.但是有问题:谁负责创建这些响应和请求对象?在窗口API中,你传递指针给OVERLAPPED结构.node.js的libuv基础,也从外部传递对象指针,使你控制分配方式.
引出了问题:如果你创建了对象,为什么有个免费的读/写函数?Win32,libuv和其他人是因为在C中没有构造器和成员函数.在D中,有,因此可以把方法放在对象中.arsd.http2两样都有:client.request创建并返回请求对象,但,你也可在外部新建HttpRequest(尽管需要设置客户端才能使它正常工作,如cookie存储).
已习惯了这样的api:
ubyte[N] buffer;
auto ret = read(file, buffer.ptr, buffer.length);
//或
ubyte[N] buffer;
Request* req = malloc(Request.sizeof);
auto error = read(file, req, buffer.ptr, buffer.length);
auto response = get_async_result(req);
但可:
ubyte[N] buffer;
ReadRequest res = new ReadRequest(buffer[], new ResponseHolder());
auto response = res.get_result();
可能不必传入ResponseHolder,因为它只是请求对象的一部分.但是单独的缓冲区很好,因为这样可更轻松复用它,这是纤程一大优点.
既然需要在异步模式下分配请求对象,成员函数应很好.
顺便,我在示例中使用了new,但我倾向于@disable new();.
因此,代码如下所示:
void mytask() {
auto timeout = scoped!Timeout(500.msecs);
auto buffer = new ubyte[](1024*32);
auto readRequest = scoped!ReadOperation(file, buffer);
auto response = waitForFirstToComplete(readRequest, timeout);
if(response is timeout)
throw new Exception("读超时"); // 取消读取挂起,因为运行`readRequest`的析构器
assert(response is readRequest);
if(!readRequest.wasSuccessful)
throw new Exception("读失败");
auto data = readRequest.filledBuffer();
//处理数据
//函数返回时析构器取消超时
}
浙公网安备 33010602011771号