草庐IT

go - 上下文取消不退出

coder 2023-06-27 原文

预计:大约在2秒

实际:无限期运行。

不明白是什么导致它无限期地运行。

package main

import (
    "context"
    "fmt"
    "time"
)

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    for i := range generator(ctx) {
        select {
        case <-time.After(2 * time.Second):
            cancel()
            return
        default:
            fmt.Println(i)
        }
    }
}

func generator(ctx context.Context) <-chan int {
    ch := make(chan int)

    go func() {
        count := 0
        for {
            select {
            case <-ctx.Done():
                return
            case ch <- count:
                count++
            }
        }
    }()

    return ch
}

最佳答案

主要问题是您从 generator(ctx) 返回的 channel 发出值的速度几乎与您读取它们的速度一样快。

time.After(2 * time.Second) 创建的 channel 几乎立即被丢弃,并且您通过生成器在每次迭代中创建一个新的超时 channel 。

如果你做了一个小小的改变;在循环创建超时 channel ,然后将其放入 select 子句中,您将看到它开始工作。

timeout := time.After(2 * time.Second)
for i := range generator(ctx) {
    select {
    case <-timeout:
        cancel()
        return
    default:
        fmt.Println(i)
    }
}

https://play.golang.org/p/zb3wn5FJuK

关于go - 上下文取消不退出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46386404/

有关go - 上下文取消不退出的更多相关文章

  1. ruby - 在 Ruby 中,在类方法的上下文中,什么是实例变量和类变量? - 2

    如果我有以下一段Ruby代码:classBlahdefself.bleh@blih="Hello"@@bloh="World"endend@blih和@@bloh到底是什么?@blih是Blah类中的一个实例变量,@@bloh是Blah类中的一个类变量,对吗?这是否意味着@@bloh是Blah的类Class中的一个变量? 最佳答案 人们似乎忽略了该方法是类方法。@blih将是常量Bleh的类Class实例的实例变量。因此:irb(main):001:0>classBlehirb(main):002:1>defself.blehirb

  2. ruby - 在 ruby​​ 中生成一个进程,捕获 stdout,stderr,获取退出状态 - 2

    我想从ruby​​rake脚本运行一个可执行文件,比如foo.exe我希望将foo.exe的STDOUT和STDERR输出直接写入我正在运行rake任务的控制台.当进程完成时,我想将退出代码捕获到一个变量中。我如何实现这一目标?我一直在玩backticks、process.spawn、system但我无法获得我想要的所有行为,只有部分更新:我在Windows上,在标准命令提示符下,而不是cygwin 最佳答案 system获取您想要的STDOUT行为。它还返回true作为零退出代码,这可能很有用。$?填充了有关最后一次system调

  3. ruby - 在 Ruby 中的另一个上下文中评估潜在的相对 URI - 2

    我在Ruby程序中有两个URI。一个肯定是绝对URI,另一个可能是绝对URI或相对URI。我想在第一个的上下文中将第二个转换为绝对URI,所以如果第一个是http://pupeno.com/blog第二个是/about,结果应该是http://pupeno.com/about.有什么想法吗? 最佳答案 Ruby的内置URI和Addressablegem,做这个简短的工作。我更喜欢Addressable,因为它功能更全面,但URI是内置的。require'uri'URI.join('http://pupeno.com/blog','/

  4. ruby-on-rails - Textmate 'Go to symbol' 相当于 Vim - 2

    在Railcasts上,我注意到一个非常有趣的功能“转到符号”窗口。它像Command-T一样工作,但显示当前文件中可用的类和方法。如何在vim中获取它? 最佳答案 尝试:helptags有各种程序和脚本可以生成标记文件。此外,标记文件格式非常简单,因此很容易将sed(1)或类似的脚本组合在一起,无论您使用何种语言,它们都可以生成标记文件。轻松获取标记文件(除了下载生成器之外)的关键在于格式化样式而不是实际解析语法。 关于ruby-on-rails-Textmate'Gotosymbol

  5. Ruby 将上下文分配给 lambda? - 2

    是否可以不为lambda分配上下文?例如:classRuledefget_rulereturnlambda{putsname}endendclassPersonattr_accessor:namedefinit_rule@name="ruby"Rule.new.get_rule.call()#shouldsay"ruby"butsaywhatobjectofclassRull,doesnothavevariablename#orself.instance_eval&Rule.new.get_ruleendend我的目标是->没有上下文的存储过程对象,并在特定位置调用之前分配上下文。可能

  6. ruby-on-rails - 取消 Rails 数据库连接 - 2

    我正在编写一个将服务器端事件与ActionController::Live结合使用的应用程序。它正在使用puma应用程序服务器。当用户连接等待来自Redis的消息时,消息Controller中的方法保持事件状态。问题是我不想通过这种方法连接到Postgres。我在六个选项卡中打开应用程序后,它有超过五个连接,由config/database.yml文件中的池大小定义,应用程序崩溃。无论如何,在调用该方法时是否可以告诉我的应用它不需要连接到数据库,因为其中没有ActiveRecord查询调用? 最佳答案 一种可能的方法是使用中间件。设

  7. ruby - 从上面的上下文返回 - 2

    这个问题的表述并不复杂,但我会尽力而为。通过我们的代码,我们有一些片段,例如response=do_something()returnresponseunlessresponse.ok?我想写一个包装器方法,这样就不需要这一步了,它看起来像这样defrr(&block)response=yieldunlessresponse.ok?#somehowdoreturnbutincontextabove(magicneededhere)endresponseend之后我就可以将上面的代码最小化为response=rr{do_something()}似乎不可能,但这是Ruby所以也许有办法吗?

  8. ruby-on-rails - 如何在不退出 IRB session 的情况下退出调试器? - 2

    这是一个长期存在的挫败感来源,但也许我遗漏了什么。如果我正在调试,并且我想退出调试器并返回到IRB或Rails控制台,“退出”将不起作用,因为它将退出IRB。“完成”似乎也与继续具有相同的效果。使用“删除”删除断点然后尝试“继续”或“完成”不起作用。有什么想法吗? 最佳答案 至少在byebug中,你可以这样做:evalreturn它具有计算当前函数的return语句的净效果。这有时会奏效,具体取决于调用堆栈的外观。现在虽然这不会删除当前断点....如果您只是想收回控制权,在大多数情况下这会做到这一点,具体取决于您的代码结构。在您的代

  9. ruby - Thin::Server#daemonize 立即退出 - 2

    我试图制作一个可执行文件,它通过Thin作为守护进程启动Sinatra应用程序。我正在使用此代码通过Sinatra应用程序调用Thin:#!/usr/bin/envrubyrequire'thin'require'app.rb'server=::Thin::Server.new('127.0.0.1',9999,App)server.log_file='tmp/thin.log'server.pid_file='tmp/thin.pid'server.daemonize这是我执行脚本时得到的日志输出:>>WritingPIDtotmp/thin.pid>>Exiting!服务器正常启动

  10. ruby - 调用 instance_eval(&lambda) 传递当前上下文时出现错误 'wrong number of arguments' - 2

    要清楚-此代码运行完美-codewithproc但如果我将Proc.new更改为lambda,则会出现错误ArgumentError:wrongnumberofarguments(1for0)这可能是因为instance_eval想要将self作为参数传递,而lambda将其视为一种方法并且不接受未知参数?有两个例子-第一个是工作:classRuledefget_ruleProc.new{putsname}endendclassPersonattr_accessor:namedefinit_rule@name="ruby"instance_eval(&Rule.new.get_rule

随机推荐