尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

WSL 容器 SDK 的 ImageProgress 数据类:镜像 pull/import/load/push 进度上报机制详解

WSL 容器 SDK 的 ImageProgress 数据类:镜像 pull/import/load/push 进度上报机制详解 WSL 容器 SDK 的 ImageProgress 数据类镜像 pull/import/load/push 进度上报机制详解【免费下载链接】WSLWindows Subsystem for Linux项目地址: https://gitcode.com/GitHub_Trending/ws/WSL导读本文围绕 WSL 仓库中 ImageProgress 数据类文档 展开深入剖析ImageProgress的字段语义、ImageProgressStatus状态机以及它如何贯穿 C 层进度回调、WinRT 投影和 C# 异步进度接口帮助读者掌握在 WSL 容器 SDKWSLC中订阅镜像操作进度的完整实践方案。什么是 ImageProgressImageProgress是 WSL 容器 SDKWSLC中专门用于承载镜像操作进度信息的数据类其作用范围覆盖 pull拉取、import导入、load加载、push推送四类镜像操作。当这些操作执行时SDK 会以异步进度回调的方式不断上报当前状态而ImageProgress正是这一批进度消息在 C# 侧的标准化表示。官方文档给出了类的完整定义public sealed class ImageProgress { public string Id { get; } public ImageProgressStatus Status { get; } public ulong CurrentBytes { get; } public ulong TotalBytes { get; } }四个属性各司其职Idstring当前进度消息所对应的镜像层 ID 或 digest。一次镜像操作通常由多个层组成每个层都有独立的进度流通过Id可以区分不同的层。StatusImageProgressStatus当前层所处的工作阶段取值来自ImageProgressStatus枚举。CurrentBytesulong当前层已处理的字节数。TotalBytesulong当前层的预估总字节数。进度状态的完整枚举ImageProgressStatus是理解ImageProgress.Status的基础其完整定义见 ImageProgressStatus 枚举文档public enum ImageProgressStatus { Unknown 0, Pulling 1, Waiting 2, Downloading 3, Verifying 4, Extracting 5, Complete 6 }这一状态序列与 Docker 客户端的层处理流程一一对应Pulling表示开始拉取Waiting表示排队等待可能受并发层数限制Downloading表示正在传输数据Verifying表示校验校验和Docker 中对应 Verifying ChecksumExtracting表示解压展开层文件Complete表示该层处理完毕对应 Docker 的 Pull complete。在 底层 C 头文件 中可以看到这组状态值与注释的对应关系WSLC_IMAGE_PROGRESS_STATUS_UNKNOWN 0, WSLC_IMAGE_PROGRESS_STATUS_PULLING 1, WSLC_IMAGE_PROGRESS_STATUS_WAITING 2, // Waiting WSLC_IMAGE_PROGRESS_STATUS_DOWNLOADING 3, // Downloading WSLC_IMAGE_PROGRESS_STATUS_VERIFYING 4, // Verifying Checksum WSLC_IMAGE_PROGRESS_STATUS_EXTRACTING 5, // Extracting WSLC_IMAGE_PROGRESS_STATUS_COMPLETE 6 // Pull complete如何获取 ImageProgressImageProgress不会凭空产生它由Session上的镜像操作接口对外提供。参考 Session 核心类文档Session为四类操作分别提供了同步版本和带进度上报的异步版本public IAsyncActionWithProgressImageProgress PullImageAsync(PullImageOptions options); public IAsyncActionWithProgressImageProgress ImportImageAsync(string path, string imageName); public IAsyncActionWithProgressImageProgress LoadImageAsync(string path); public IAsyncActionWithProgressImageProgress PushImageAsync(PushImageOptions options);这些方法返回IAsyncActionWithProgressImageProgress消费方只需订阅其Progress事件即可实时收到ImageProgress实例。这也解释了为什么ImageProgress的所有属性都是只读的——它完全由 SDK 内部生成并推送调用方只负责读取展示。在 WinRT IDL 定义 中可以看到完全一致的异步签名设计C# API 正是这一 WinRT 投影的托管形态。从 C 回调到 WinRT 的完整链路ImageProgress的生成链路贯穿三层实现理解这条链路有助于把握字段语义的出处C 层结构体底层 SDK 使用 WslcImageProgressMessage 承载原始进度数据typedef struct WslcImageProgressMessage { _Out_ PCSTR id; // layer ID or digest _Out_ WslcImageProgressStatus status; // Downloading, Extracting, etc. _Out_ WslcImageProgressDetail detail; } WslcImageProgressMessage;兼容层转换ProgressCallback.cpp 负责将原生回调转换为 WinRT 可消费的消息结构。WinRT 包装类ImageProgress.h 与 ImageProgress.cpp 实现ImageProgress的 WinRT 投影构造时从WslcImageProgressMessage逐字段拷贝ImageProgress::ImageProgress(const WslcImageProgressMessage* progress) : m_id(winrt::to_hstring(progress-id)), m_status(static_castImageProgressStatus(progress-status)), m_currentBytes(progress-detail.currentBytes), m_totalBytes(progress-detail.totalBytes) { }可以看到CurrentBytes/TotalBytes直接来自detail子结构中的currentBytes/totalBytes字段与文档中的ulong类型完全对应。使用示例在 C# 中订阅镜像拉取进度文档给出的示例展示了最基础的消费方式——将ImageProgress格式化为一行可读文本void PrintImageProgress(ImageProgress progress) Console.WriteLine(${progress.Status,-12} {progress.Id} {progress.CurrentBytes}/{progress.TotalBytes});这里{progress.Status,-12}表示状态字段左对齐、占 12 个字符宽度输出形如Downloading sha256:abc123... 10485760/31457280 Extracting sha256:abc123... 20971520/31457280 Pull complete sha256:abc123... 31457280/31457280结合 Session 的完整实战写法单看PrintImageProgress还不够将它接入真实操作才能发挥价值。结合 Session 文档 中的异步示例一次带进度显示的镜像拉取可以这样写var pull session.PullImageAsync(new PullImageOptions(docker.io/library/alpine:latest)); pull.Progress (op, progress) PrintImageProgress(progress); await pull;IAsyncActionWithProgressImageProgress.Progress事件的委托签名是AsyncActionProgressHandlerImageProgress两个参数分别为异步操作本身和本次进度实例。在实际应用中往往还需要引入按Id分组的累计逻辑——因为同一层在Downloading阶段会收到大量字节更新的回调而每个进度实例只携带本次增量对应的当前值界面层需要自行维护每个层的最近状态。实战注意点TotalBytes 是预估而非精确值在编写进度条时要特别注意TotalBytes的语义。在 CLI 进度渲染实现 中有这样一段关键注释Docker 上报的 total 是压缩后层大小的预估实际传输的字节数可能超过该值。此时应丢弃 total避免显示超过 100% 的计数。对应实现中当current total时只显示当前字节数、不再拼接/total。这意味着展示层不应把TotalBytes当作精确上限进度条应做封顶处理Math.Min(current, total)并在current超出total时直接视为完成。底层视角SDK 侧的进度上报与渲染策略深入仓库源码可以看到ImageProgress数据在下游消费时有两种典型形态这也为上层 API 设计提供了参照。原生 C 回调接口底层 SDK 通过函数指针回调上报进度定义于 wslcsdk.htypedef HRESULT(CALLBACK* WslcContainerImageProgressCallback)(const WslcImageProgressMessage* progress, PVOID context);该回调挂接在各操作选项结构体中如WslcPullImageOptionsprogressCallback/progressCallbackContext字段由兼容层 ProgressCallback.h 的CreateIf工厂按需包装后转发给 WinRT 层。CLI 终端的交互式渲染wslc 服务的 ImageProgressCallback 展示了进度的另一种消费方式在 VT 终端上每个层独占一行通过光标移动在同一行内原地重绘进度条形式当输出被重定向非 VT 环境时则退化为按状态去重打印的日志流。其中对进度条填充、控制台宽度截断、UTF-16 代理对保护的细节处理为自定义进度 UI 提供了现成的工程参考。测试验证仓库测试 WslcSdkTests.cpp 中的ImageProgressCallback测试用例通过启动本地 registry、对hello-world:latest执行 push 操作来验证进度回调确实被触发并断言回调收到的状态不是UNKNOWN。这从测试角度印证了只要挂接了回调镜像操作期间就一定会收到带有效状态的ImageProgress消息。与其他数据类的关系ImageProgress属于 C# Data Classes 目录 中的一员该目录还包含ImageInfo、ContainerPortMapping、ContainerVolume、InstallProgress、ServiceVersion等数据类。与ImageProgress最相关的是ImageInfo描述镜像的静态元信息名称、ID、大小等由Session.GetImages()返回代表结果ImageProgress描述镜像操作的动态过程由PullImageAsync等异步接口推送代表过程。二者配合可以构建完整的镜像管理 UI用ImageInfo展示已安装镜像清单用ImageProgress展示正在进行的拉取/推送任务。小结ImageProgress虽然只是一个四字段的简单数据类却是 WSL 容器 SDK 镜像操作体验的关键一环。理解它的关键在于把握三条线索Status对应完整的层处理状态机Pulling→Waiting→Downloading→Verifying→Extracting→CompleteId标识具体层CurrentBytes/TotalBytes提供量化进度——且TotalBytes是预估上限展示层需要容忍超量情况。将其接入Session的四个*Async异步接口的Progress事件即可在 C# 应用中实现与 Docker CLI 相当的实时进度体验。【免费下载链接】WSLWindows Subsystem for Linux项目地址: https://gitcode.com/GitHub_Trending/ws/WSL创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表