Elixir 处理:向下和#参考<&燃气轮机;任务超时后的消息

Elixir 处理:向下和#参考<&燃气轮机;任务超时后的消息,elixir,Elixir,我正在生成一个带有Task.async/3的函数,并使用带有超时的Task.yield/2获得结果。函数完成后,调用进程将收到两条消息: {#Reference<0.2781211517.3250323457.144521>, the_result_of_the_function} 由监视器发送,通知被监视的进程(任务)已关闭 如果任务在超时之前完成,task.yield/2将这些邮件从邮箱中取出并返回正确的结果。但是,如果任务在超时后完成,task.yield/2返回nil,当这

我正在生成一个带有
Task.async/3
的函数,并使用带有超时的
Task.yield/2
获得结果。函数完成后,调用进程将收到两条消息:

{#Reference<0.2781211517.3250323457.144521>, the_result_of_the_function}
由监视器发送,通知被监视的进程(任务)已关闭

如果任务在超时之前完成,
task.yield/2
将这些邮件从邮箱中取出并返回正确的结果。但是,如果任务在超时后完成,
task.yield/2
返回
nil
,当这两条消息到达时,程序流已经在其他地方了

我实现了两个
handle\u info
处理程序来将这些邮件从邮箱中取出。然而,这可能是一个坏主意,因为我无法仅从过期任务中获取消息(我看不到任何方法“注册”超时任务的
#引用
),我可能会在
任务读取有效消息之前删除它们。yield/2

我遗漏了什么以及如何解决这个问题?

的文档建议了以下方法:

如果在收到来自任务的消息之前时间已过,此功能将返回
nil
,监视器将保持激活状态。[…]如果任务在超时毫秒内没有响应,您打算关闭该任务,则应将其与
shutdown/1
链接在一起,如下所示:

case Task.yield(task, timeout) || Task.shutdown(task) do
  {:ok, result} ->
    result
  nil ->
    Logger.warn "Failed to get a result in #{timeout}ms"
    nil
end

Grrr RFTFM!尽管如此:由于
Task.yield(Task,timeout)| | Task.shutdown(Task)
不是原子的,没有任何东西可以阻止这种情况:1/
Task.yield()
超时,2/调度程序给异步任务一些时间来完成发送消息的任务,3/
Task.shutdown()
执行,但不再需要关机,因此,调用进程的邮箱最终已满。这对于
任务来说可能更重要。yield_many()
(这是我的实际用例),因为有更多的处理(更多的异步任务),这增加了被调度程序中断的可能性。这是否正确?RTM再次指出,“[使用此方法]可确保如果任务在超时后但在调用shutdown/1之前完成,您仍将获得结果,因为shutdown/1旨在处理此情况并返回结果。“;-)文档中还有一个示例,说明如何在使用Task.yield\u many时应用Task.shutdown:
case Task.yield(task, timeout) || Task.shutdown(task) do
  {:ok, result} ->
    result
  nil ->
    Logger.warn "Failed to get a result in #{timeout}ms"
    nil
end