我有几个任务,我正在异步运行.根据输入,一个或多个可能会运行很长时间,但只有一个任务将返回:success消息.
slowtask = Task.async(slow())
fasttask = Task.async(fast())
Run Code Online (Sandbox Code Playgroud)
如何捕获上述两个任务中的第一个完成,而不必等待另一个?我已经尝试过了Task.find/2,但是由于它是用enum实现的,所以它似乎在找到ref/message之前等待所有的退出信号.我的另一个想法是对此进行调查Stream.cycle,忽略仍然存在的任务并捕获已退出的任务.看来这种灵丹妙药不喜欢以这种方式进行民意调查.
目前还没有简单的方法在Elixir上做到这一点.您最好的选择是,如果您只是在给定进程中等待这些消息,则是这样的:
defmodule TaskFinder do
def run do
task1 = Task.async fn -> :timer.sleep(1000); 1 end
task2 = Task.async fn -> :timer.sleep(5000); 2 end
await [task1, task2]
end
# Be careful, this will receive all messages sent
# to this process. It will return the first task
# reply and the list of tasks that came second.
def await(tasks) do
receive do
message ->
case Task.find(tasks, message) do
{reply, task} ->
{reply, List.delete(tasks, task)}
nil ->
await(tasks)
end
end
end
end
IO.inspect TaskFinder.run
Run Code Online (Sandbox Code Playgroud)
请注意,您也可以使用此模式在GenServer中生成任务并用于Task.find/2查找匹配的模式.我还将此示例添加到Elixir文档中.
| 归档时间: |
|
| 查看次数: |
1489 次 |
| 最近记录: |