当前位置: 首页 > news >正文

学做网站论坛教程下载h5游戏大全在线玩

学做网站论坛教程下载,h5游戏大全在线玩,2000元代理微信朋友圈广告,惠州seo快速排名目录 基于现有的 context 创建新的 context 现有创建方法的问题 Go 1.21 中的 context.WithoutCancel 函数 Go 版本低于 1.21 该怎么办#xff1f; 在 Golang 中#xff0c;context 包提供了创建和管理上下文的功能。当需要基于现有的 context.Context 创建新的 context …目录 基于现有的 context 创建新的 context 现有创建方法的问题 Go 1.21 中的 context.WithoutCancel 函数 Go 版本低于 1.21 该怎么办 在 Golang 中context 包提供了创建和管理上下文的功能。当需要基于现有的 context.Context 创建新的 context 时通常是为了添加额外的控制信息或为了满足特定的生命周期需求。 基于现有的 context 创建新的 context 可以基于现有的 context.Context 创建一个新的 context对应的函数有 context.WithCancel、context.WithDeadline、context.WithTimeout 或 context.WithValue。这些函数会返回一个新的 context.Context 实例继承了原来 context 的行为并添加了新的行为或值。使用 context.WithValue 函数创建的简单示例代码如下 package mainimport contextfunc main() {// 假设已经有了一个context ctxctx : context.Background()// 可以通过context.WithValue创建一个新的contextkey : myKeyvalue : myValuenewCtx : context.WithValue(ctx, key, value)// 现在newCtx包含了原始ctx的所有数据加上新添加的键值对 } 使用 context.WithCancel 函数创建简单示例代码如下 package mainimport contextfunc main() {// 假设已经有了一个context ctxctx : context.Background()// 创建一个可取消的contextnewCtx, cancel : context.WithCancel(ctx)// 当完成了newCtx的使用可以调用cancel来取消它// 这将释放与该context相关的资源defer cancel() } 现有创建方法的问题 先说一个使用场景一个接口处理完基本的任务之后后续一些处理的任务放使用新开的 Goroutine 来处理这时候会基于当前的 context 创建一个 context可以使用上面提到的方法来创建 给 Goroutine 使用也不需要控制 Goroutine 的超时时间。 这种场景下Goroutine 的声明周期一般都会比这个接口的生命周期长这就会出现一个问题——当前接口请求所属的 Goroutine 退出后会导致 context 被 cancel进而导致新开的 Goroutine 中的 context 跟着被 cancel 从而导致程序异常。看一个示例 package mainimport (bytescontexterrorsfmtionet/httpgithub.com/gin-gonic/gin )func main() {r : gin.New()r.GET(/test, func(c *gin.Context) {// 父 context有使用取消功能ctx, cancel : context.WithCancel(c)defer cancel()// 创建子 context 给新开的 Goroutine 使用ctxCopy, _ : context.WithCancel(ctx)go func() {err : TestPost(ctxCopy)fmt.Println(err)}()})r.Run(:8080) }func TestPost(ctx context.Context) error {fmt.Println(goroutine...)buffer : bytes.NewBuffer([]byte({xxx:xxx}))request, err : http.NewRequest(POST, http://xxx.luduoxin.com/xxx, buffer)if err ! nil {return err}request.Header.Set(Content-Type, application/json)client : http.Client{}rsp, err : client.Do(request.WithContext(ctx))if err ! nil {return err}defer func() {_ rsp.Body.Close()}()if rsp.StatusCode ! http.StatusOK {return errors.New(response exception)}_, err io.ReadAll(rsp.Body)if err ! nil {return err}return nil } 运行代码在浏览器中访问 http://127.0.0.1:8080/test控制台会打印如下错误信息 goroutine... Post http://xxx.luduoxin.com/xxx: context canceled 可以看出因为父级 context 被 cancel导致子 context 也被 cancel从而导致程序异常。因此需要一种既能继承父 context 所有的 value 信息又能去除父级 context 的 cancel 机制的创建函数。 Go 1.21 中的 context.WithoutCancel 函数 这种函数该如何实现呢其实 Golang 从 1.21 版本开始为我们提供了这样一个函数就是 context 包中的 WithoutCancel 函数。源代码如下 func WithoutCancel(parent Context) Context {if parent nil {panic(cannot create context from nil parent)}return withoutCancelCtx{parent} }type withoutCancelCtx struct {c Context }func (withoutCancelCtx) Deadline() (deadline time.Time, ok bool) {return }func (withoutCancelCtx) Done() -chan struct{} {return nil }func (withoutCancelCtx) Err() error {return nil }func (c withoutCancelCtx) Value(key any) any {return value(c, key) }func (c withoutCancelCtx) String() string {return contextName(c.c) .WithoutCancel } 原理其实很简单主要功能是创建一个新的 context 类型继承了父 context 的所有属性但重写了 Deadline、Done、Err、Value 几个方法当父 context 被取消时不会触发任何操作。 Go 版本低于 1.21 该怎么办 如果 Go 版本低于 1.21 其实也很好办按照 Go 1.21 中的实现方式自己实现一个就可以了代码可以进一步精简示例代码如下 func WithoutCancel(parent Context) Context {if parent nil {panic(cannot create context from nil parent)}return withoutCancelCtx{parent} }type withoutCancelCtx struct {context.Context }func (withoutCancelCtx) Deadline() (deadline time.Time, ok bool) {return }func (withoutCancelCtx) Done() -chan struct{} {return nil }func (withoutCancelCtx) Err() error {return nil } 使用自己实现的这个版本再跑一下之前的示例代码如下 package mainimport (bytescontexterrorsfmtionet/httptimegithub.com/gin-gonic/gin )func main() {r : gin.New()r.GET(/test, func(c *gin.Context) {// 父 context有使用取消功能ctx, cancel : context.WithCancel(c)defer cancel()// 创建子 context 给新开的 Goroutine 使用ctxCopy : WithoutCancel(ctx)go func() {err : TestPost(ctxCopy)fmt.Println(err)}()})r.Run(:8080) }func WithoutCancel(parent Context) Context {if parent nil {panic(cannot create context from nil parent)}return withoutCancelCtx{parent} }type withoutCancelCtx struct {context.Context }func (withoutCancelCtx) Deadline() (deadline time.Time, ok bool) {return }func (withoutCancelCtx) Done() -chan struct{} {return nil }func (withoutCancelCtx) Err() error {return nil }func TestPost(ctx context.Context) error {fmt.Println(goroutine...)buffer : bytes.NewBuffer([]byte({xxx:xxx}))request, err : http.NewRequest(POST, http://xxx.luduoxin.com/xxx, buffer)if err ! nil {return err}request.Header.Set(Content-Type, application/json)client : http.Client{}rsp, err : client.Do(request.WithContext(ctx))if err ! nil {return err}defer func() {_ rsp.Body.Close()}()if rsp.StatusCode ! http.StatusOK {return errors.New(response exception)}_, err io.ReadAll(rsp.Body)if err ! nil {return err}return nil }type Context interface {Deadline() (deadline time.Time, ok bool)Done() -chan struct{}Err() errorValue(key any) any } 运行代码在浏览器中访问 http://127.0.0.1:8080/test发现不再报父 context 被 cancel 导致的报错了。
http://www.w-s-a.com/news/721283/

相关文章:

  • 做百度手机网站推广普通话的宣传标语
  • 记事本可以做网站吗网站服务器是主机吗
  • 手机网站被拦截怎么办怎么解决东营建设信息网网
  • 外贸网站模板免费微信网站开发技术
  • 视频盗版网站怎么做福州网站seo
  • 成都金铭 网站建设做网站包含的技术
  • 长沙的网站建设公司哪家好做网站应选那个主题
  • 公司网站百度搜不到如何自己做一个网站
  • 学生如何建设网站网站开发程序
  • 网站建设公司哪家好 皆来磐石网络网站建设"淘宝网" 在颜色选取和搭配方面有哪些值得学习的地方.
  • 网站如何做移动规则适配北京住房与城乡建设部网站
  • 课堂阵地建设网站wordpress运行机制
  • 网站建设的需求方案企业网站建设费用明细
  • 创口贴网站模板京创影视app
  • 团购网站建设目的网站有很多304状态码
  • 运用阿里云怎么做网站外资企业可以在中国境内做网站吗
  • 云南住房和城乡建设局网站西安做官网的公司
  • 企业网站图片上传网站建设和应用的情况
  • 网站不显示内容吗聊城网架公司
  • 南昌网站建设企业网站托管外包怎么做
  • 做非洲外贸的网站网站可以用PS设计吗
  • PHP搭建IDC网站青岛福瀛建设集团网站
  • 安徽网站优化多少钱软件界面设计的基本原则
  • 网站建设动态页面修改删除dnf卖飞机的网站怎么做的
  • 万网是做什么的seo综合
  • 网站关键词分隔符php网站开发平台下载
  • 郑州那家做网站便宜商业计划书免费word版
  • 秦时明月的个人网站怎么做网站开发公司需要招聘哪些人
  • 广告网站建设制作设计服务商安卓app软件定制
  • 公司网站设计与实现中国职业培训在线官方网站