Skip to content

bug: [P2] Dispose 后调用 WaitForConnectedAsync 会创建永不完成的等待器 #65

Description

@CSJ608

评审基线:StreamFrame 2.6.0,提交 4b892d9eaa11cf003b5d10793e735b0604bc17ed(2026-09-08 仓库评审)。

问题与影响

P2,已独立复现。 Shutdown 仅取消当时已存在的 _whenConnected;Dispose 完成后再次调用 WaitForConnectedAsync,会新建没有任何完成者的 TCS。不传调用方取消令牌时永久等待;Dispose 与首次等待并发也存在对应窗口。

位置:src/StreamFrame/Connection/StreamConnection.cs:1046,GetOrCreateWhenConnected 与 Shutdown。
现有测试覆盖的是“先等待,再 Dispose”,缺少反向顺序和并发:test/StreamFrame.Tests/ConnectionUsabilityTests.cs:82。

复现

Windows、.NET 8.0.30;在现有测试项目可复用 StringCodec.Instance:

var connection = new StreamConnection<string>(
    new LengthPrefixFramer(), StringCodec.Instance,
    IPAddress.Loopback, 12345, isActive: true);
await connection.DisposeAsync();
var wait = connection.WaitForConnectedAsync();
await Task.Delay(100);
Assert.True(wait.IsCompleted); // 当前失败:WaitingForActivation

此路径不需要启动网络连接。

建议与验收

  • 明确终态调用的失败语义,并与接口文档“Dispose 使等待取消”对齐。
  • Dispose 已完成后调用,无调用方令牌也及时取消/失败。
  • 等待器注册与 Shutdown 并发时不遗留挂起任务;仅入口检查 IsDisposed 不足以关闭注册竞态。
  • 保留首次连接、跨重试、已连接立即完成、调用方取消、生命周期令牌取消的行为。
  • 用可控同步点或重复竞速测试验证终态不再产生孤立等待器。

实施按 AGENTS.md:从最新 main 建分支、同步 CHANGELOG Unreleased、通过 Release build/test、走 PR;本 Issue 仅登记工作,不代表已实施修复。

Activity

  1. CSJ608 commented on Sep 8, 2026

    @CSJ608
    OwnerAuthor

    修复已通过 PR #75 rebase 合并(b23b86c),保持现有“连接 Dispose 时等待任务取消”契约。注册后终态复查覆盖 Shutdown 清空之后的迟到首次注册,无公共 API/异常契约变更。

    最终版测试在旧实现上 3 失败/5 通过;修复后 Release build 零警告错误,net8/net10/net48 各 119 测试通过,含每框架 1000 次首次注册与 Dispose 竞速。PR CI/AOT/CodeQL 全绿,实施分支已删除;正核对合并后的 main CI。

  2. CSJ608 commented on Sep 8, 2026

    @CSJ608
    OwnerAuthor

    补充:合并后 main CI 已通过:https://github.com/CSJ608/StreamFrame/actions/runs/34205336886 。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions