# a 建筑可重复使用的短时处决图书馆

<!--category-- ASP.NET, Architecture, Systems Design, Async, DI -->
<datetime class="hidden">2025-12-12T14:00</datetime>

内 **[部分#1:火和唐・'t *不错* 忘记](/blog/fire-and-dont-quite-forget-ephemeral-execution)**“,”我们探索了时间处决背后的理论“-” 绑定“,” 私人“MS K3” 可调试的“同步”工作流程,这些流程记忆犹新,以至于有用,然后蒸发“MSC4”

此文章将该图案转换为可重复使用的库, 您可以将其投放到任何 {. nET project .}\

## NUGET!!!

这现在也出现在大多数卢西德.\ ephearals Nuget 软件包中 [超过 @20 @ mostlucid@ . @epheperals 模式和%'#atoms@'}](https://www.nuget.org/packages?q=mostlylucid.ephemeral&includeComputedFrameworks=true&prerel=true&sortby=created-desc).

[![Nuget 元数](https://img.shields.io/nuget/v/mostlylucid.ephemeral.svg)](https://www.nuget.org/packages/mostlylucid.ephemeral)
[![驾照许可证](https://img.shields.io/badge/license-Unlicense-blue.svg)](../../UNLICENSE)

## 源代码文件

完整源代码在 [基特Hub 库](https://github.com/scottgal/mostlylucid.atoms)

[TOC]

---


## 前后

在这里,' @%s 我们这是在替换#:}

```csharp
// ❌ Before: Fire-and-forget black hole
_ = Task.Run(() => ProcessAsync(item));
// No visibility. No debugging. No idea if it worked.

// ❌ Or: Blocking everything
await ProcessAsync(item);  // Hope you like waiting...
```

和什么我们'正在建设\:

```csharp
// ✅ After: Trackable, bounded, debuggable
await coordinator.EnqueueAsync(item);

// Instant visibility
Console.WriteLine($"Pending: {coordinator.PendingCount}");
Console.WriteLine($"Active: {coordinator.ActiveCount}");
Console.WriteLine($"Failed: {coordinator.TotalFailed}");

// Full operation history
var snapshot = coordinator.GetSnapshot();
var failures = coordinator.GetFailed();
```

相同的同步执行@. 完全可观察性 @. 没有保留用户数据\.

---


## 快速启动

最常见的模式 @-在DI注册协调员,并输入#:

```csharp
// Program.cs
services.AddEphemeralWorkCoordinator<TranslationRequest>(
    async (request, ct) => await TranslateAsync(request, ct),
    new EphemeralOptions { MaxConcurrency = 8 });

// Your service
public class TranslationService(EphemeralWorkCoordinator<TranslationRequest> coordinator)
{
    public async Task TranslateAsync(TranslationRequest request)
    {
        await coordinator.EnqueueAsync(request);
        // Returns immediately - work happens in background
    }

    public object GetStatus() => new
    {
        pending = coordinator.PendingCount,
        active = coordinator.ActiveCount,
        completed = coordinator.TotalCompleted,
        failed = coordinator.TotalFailed
    };
}
```

---


## 需要哪个变式

```text
┌─────────────────────────────────────────────────────────────────┐
│                    DECISION TREE                                │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Processing a collection once?                                  │
│  └─► EphemeralForEachAsync<T> (ParallelEphemeral.cs)            │
│                                                                 │
│  Need a long-lived queue that accepts items over time?          │
│  └─► EphemeralWorkCoordinator<T>                                │
│                                                                 │
│  Need per-entity ordering (user commands, tenant jobs)?         │
│  └─► EphemeralKeyedWorkCoordinator<TKey, T>                     │
│                                                                 │
│  Need to capture results (fingerprints, summaries)?             │
│  └─► EphemeralResultCoordinator<TInput, TResult>                │
│                                                                 │
│  Need multiple coordinators with different configs?             │
│  └─► IEphemeralCoordinatorFactory<T> (like IHttpClientFactory)  │
│                                                                 │
│  Need dynamic concurrency adjustment at runtime?                │
│  └─► Set EnableDynamicConcurrency = true, call SetMaxConcurrency│
│                                                                 │
└─────────────────────────────────────────────────────────────────┘
```

---


## 配置对象

从 [时间选择@. @cs](https://github.com/scottgal/mostlylucidweb/blob/main/Mostlylucid/Helpers/Ephemeral/EphemeralOptions.cs):

```csharp
public sealed class EphemeralOptions
{
    // Concurrency control
    public int MaxConcurrency { get; init; } = Environment.ProcessorCount;
    public int MaxConcurrencyPerKey { get; init; } = 1;
    public bool EnableDynamicConcurrency { get; init; } = false;

    // Window management
    public int MaxTrackedOperations { get; init; } = 200;
    public TimeSpan? MaxOperationLifetime { get; init; } = TimeSpan.FromMinutes(5);

    // Fair scheduling (keyed coordinator)
    public bool EnableFairScheduling { get; init; } = false;
    public int FairSchedulingThreshold { get; init; } = 10;

    // Signal-reactive processing
    public IReadOnlySet<string>? CancelOnSignals { get; init; }
    public IReadOnlySet<string>? DeferOnSignals { get; init; }
    public int MaxDeferAttempts { get; init; } = 10;
    public TimeSpan DeferCheckInterval { get; init; } = TimeSpan.FromMilliseconds(100);

    // Signal infrastructure
    public SignalSink? Signals { get; init; }
    public SignalConstraints? SignalConstraints { get; init; }
    public Action<SignalEvent>? OnSignal { get; init; }

    // Async signal handling
    public Func<SignalEvent, CancellationToken, Task>? OnSignalAsync { get; init; }
    public int MaxConcurrentSignalHandlers { get; init; } = 4;
    public int MaxQueuedSignals { get; init; } = 1000;

    // Observability
    public Action<IReadOnlyCollection<EphemeralOperationSnapshot>>? OnSample { get; init; }
}
```

### 关键设计决定

- **最大币值** CPU 数的默认值@-}对于 CPO - 来说是明智的。 对于 I/\ @O\-}(对于IMSK3+OQMSK4), CPI 计数={MSK0. Q} 对于 PCU msk1} <bound working_BARBAR_b0}
- **启用动态货币** 能够通过 `SetMaxConcurrency()` -使用自定义的大门而不是 `SemaphoreSlim`.
- **取消信号@ / @ deferOnSignals** 设置协调器信号@ - @ reactive @ MS K1 @ 它们响应环境系统状态 @ I(# patter匹配支持 `*`/`?`@/_comma 列表@).
- **信号** 是同步@ ; @ 用于 Async fan @ MS K1_ out 使用 `SignalDispatcher` 或 `AsyncSignalProcessor` 控制器内部 @. @%
- **信号约束** 防止无穷无尽的信号循环和周期探测及深度限值@.

---


## 《快照记录》

从 [抓图 @ .% cs](https://github.com/scottgal/mostlylucidweb/blob/main/Mostlylucid/Helpers/Ephemeral/Snapshots.cs):

```csharp
public sealed record EphemeralOperationSnapshot(
    long Id,
    DateTimeOffset Started,
    DateTimeOffset? Completed,
    string? Key,
    bool IsFaulted,
    Exception? Error,
    TimeSpan? Duration,
    IReadOnlyList<string>? Signals = null,
    bool IsPinned = false)
{
    public bool HasSignal(string signal) => Signals?.Contains(signal) == true;
}

// For result-capturing coordinators
public sealed record EphemeralOperationSnapshot<TResult>(
    long Id,
    DateTimeOffset Started,
    DateTimeOffset? Completed,
    string? Key,
    bool IsFaulted,
    Exception? Error,
    TimeSpan? Duration,
    TResult? Result,
    bool HasResult,
    IReadOnlyList<string>? Signals = null,
    bool IsPinned = false);
```

这是 **仅包含元数据**@. @ 注意什么 @ ' @%s *否* 这里 :

- 无有效载荷
- 无输入数据
- 无用户内容

足以回答“"”和“,”时发生的事情,

---


## 与其它方法相比如何

.NET为您提供多种平行工作方式@.这里 @'

### 平行.@ forEachAsync @(.#NET$6+)

```csharp
await Parallel.ForEachAsync(items,
    new ParallelOptions { MaxDegreeOfParallelism = 4 },
    async (item, ct) => await ProcessAsync(item, ct));
```

**最佳**: 简单平行的收藏处理 您需要可见度}.

**其缺乏的**:

- 无业务跟踪
- 没有相继执行
- 没有可见度进入正在运行的 @ ' @%s

**使用时短时间**: 您需要调试@ /} @ objective {% 2} please\ -_ key 订购 *,} 或信号 <-\ reactive programing\ MS K6}

### TPL 数据流

```csharp
var block = new ActionBlock<T>(
    async item => await ProcessAsync(item),
    new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 4 });

foreach (var item in items)
    block.Post(item);

block.Complete();
await block.Completion;
```

**最佳**“:” 复杂数据流管道,与分支连接“,” 合并“MS K2” 批发@.

**做得好的东西**:

- 丰富的管道成分 @ (link blocks together_ )
- 正在转换 , 广播
- 连接后端的容量@ - @ pressure

**使用 TPL 数据流**: 您需要复杂的管道布局表 * @(_fan}-Out*, fan{-_in,有条件的路由 *).#

**使用时短时间**: 您需要操作跟踪@, 简单 API}, 或者信号-反应协调 *.

### 系统@ . @ treading @ MS K1 @ 通道

```csharp
var channel = Channel.CreateBounded<T>(100);

// Producer
foreach (var item in items)
    await channel.Writer.WriteAsync(item);
channel.Writer.Complete();

// Consumer (multiple workers)
var workers = Enumerable.Range(0, 4).Select(async _ =>
{
    await foreach (var item in channel.Reader.ReadAllAsync())
        await ProcessAsync(item);
});
await Task.WhenAll(workers);
```

**最佳**你控制双方的消费模式 .

**做得好的东西**:

- 表现出色
- BackM-通过连接的频道发出压力
- 生产者和消费者的分离

**使用频道时**建立定制基础设施,需要最大控制... .......

**使用时短时间**:}您想要没有锅炉板的操作跟踪和可观察性吗?

### 波利

```csharp
var policy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetryAsync(3, attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)));

await policy.ExecuteAsync(() => ProcessAsync(item));
```

**最佳**“:”抗御力政策“(retry @,断路器 ,超时@)单项操作”“MS K5

**使用 Polly**您需要针对个人电话的复原力 .

**使用时短时间**: 您需要协调许多操作 与环境意识.

**结合他们**:在您的时空工作机构里使用 Polly 来完成您的工作

### 质量中转@/ @NServiciceBus

**最佳**使用耐久队列的全套服务发送信息@.

**使用信息巴士时**“: 工作必须活过重开关的流程@, 覆盖多种服务 @, 或要求有保证地交付=.

**使用时短时间**:工作在 @-process@, does\'}不需要耐久性 @MS K4,你想要轻量级的可观察性#.

### 比较表

@|Q 接近@|QQBound_|Q跟踪 @MS K3QPer-QKQKey#|QSignals @|ZSOMK7QCLEANING @MSKO8}(复杂程度%|)
|----------|:-------:|:--------:|:-------:|:-------:|:-------------:|:----------:|
| `Parallel.ForEachAsync` | MS K1 NSK2 MASK3 I| MPK5 MSSK6 USK7 TMK8 N/A | 低|
|+TPL数据流 @|+ @MS K2+#|} @❌+ |+ @#❌+ @ @MSC7+ @NSK8+ @|_❌+~|#高
❌ MS K6 @| @❌ |#❌#|}中度| @
{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}|波里 | N/A | NSK4N/A {\fnarial black\fs12\bord0\shad1\1cH00FFFF\b0}
| @背景服务 @| ❌#|} @❌ @ @MS K5 @#❌ #|#❌ @~|_❌(MS K11中度□|)*
-=YTET -伊甸园字幕组=- 翻译:
| **短期图书馆** | @✅} @MS K2 @ @✅#@| @ @#|(✅Q) @#✅~|_ @ @ @NSK9

---


## Ephemeral ForEachAssync: 单MS K1Shot 版本

从 [平行时间@. @cs](https://github.com/scottgal/mostlylucidweb/blob/main/Mostlylucid/Helpers/Ephemeral/ParallelEphemeral.cs):

```csharp
// Simple parallel processing with tracking
await items.EphemeralForEachAsync(
    async (item, ct) => await ProcessAsync(item, ct),
    new EphemeralOptions { MaxConcurrency = 8 });

// With keyed execution (per-user sequential)
await commands.EphemeralForEachAsync(
    cmd => cmd.UserId,  // Key selector
    async (cmd, ct) => await ExecuteCommandAsync(cmd, ct),
    new EphemeralOptions
    {
        MaxConcurrency = 32,
        MaxConcurrencyPerKey = 1  // Sequential per user
    });
```

### 为何关键管道重要

想象一下正在处理用户命令@:

- 用户 A 发送命令 @ 1, @\ MS K1} @ MPK2
- 用户 B 发送命令 @ 4, @\ MS K1} @ I6

没有按键 ,这些可能执行的 as @: @ @1, 4, @#2,# @MS K53, @{6#-跨婚}.#

与 `MaxConcurrencyPerKey = 1`:

- 用户 A'%s 命令按顺序执行
- 用户 B' @%s 命令按以下顺序执行
- 但A和B可以平行运行

这是 **以全球平行为单位** *-*}对于实体内部的秩序问题的关键系统来说

---


## 工作协调员=:Long-Lived队列

从 [短期工作协调员](https://github.com/scottgal/mostlylucidweb/blob/main/Mostlylucid/Helpers/Ephemeral/EphemeralWorkCoordinator.cs):

```csharp
await using var coordinator = new EphemeralWorkCoordinator<TranslationRequest>(
    async (request, ct) => await TranslateAsync(request, ct),
    new EphemeralOptions
    {
        MaxConcurrency = 8,
        MaxTrackedOperations = 500,
        EnableDynamicConcurrency = true  // Allow runtime adjustment
    });

// Enqueue items over time
await coordinator.EnqueueAsync(new TranslationRequest("Hello", "es"));

// Check status anytime
Console.WriteLine($"Pending: {coordinator.PendingCount}");
Console.WriteLine($"Active: {coordinator.ActiveCount}");

// Get snapshots
var snapshot = coordinator.GetSnapshot();
var running = coordinator.GetRunning();
var failed = coordinator.GetFailed();
var completed = coordinator.GetCompleted();

// Control flow
coordinator.Pause();   // Stop pulling new work
coordinator.Resume();  // Continue

// Adjust concurrency at runtime (requires EnableDynamicConcurrency)
coordinator.SetMaxConcurrency(16);

// Pin important operations to survive eviction
coordinator.Pin(operationId);
coordinator.Unpin(operationId);
coordinator.Evict(operationId);

// When done
coordinator.Complete();
await coordinator.DrainAsync();
```

### 使用 IAsync 连续流

```csharp
await using var coordinator = EphemeralWorkCoordinator<Message>.FromAsyncEnumerable(
    messageStream,  // IAsyncEnumerable<Message>
    async (msg, ct) => await ProcessMessageAsync(msg, ct),
    new EphemeralOptions { MaxConcurrency = 16 });

await coordinator.DrainAsync();
```

---


## 关键协调员: PerMS K1实体管道

从 [时间和工作协调员](https://github.com/scottgal/mostlylucidweb/blob/main/Mostlylucid/Helpers/Ephemeral/EphemeralKeyedWorkCoordinator.cs):

```csharp
await using var coordinator = new EphemeralKeyedWorkCoordinator<string, Command>(
    cmd => cmd.UserId,  // Key selector
    async (cmd, ct) => await ExecuteCommandAsync(cmd, ct),
    new EphemeralOptions
    {
        MaxConcurrency = 32,
        MaxConcurrencyPerKey = 1,      // Per-user sequential
        EnableFairScheduling = true,   // Prevent hot user starvation
        FairSchedulingThreshold = 10   // Reject if user has 10+ pending
    });

// TryEnqueue returns false if fair scheduling rejects
if (!coordinator.TryEnqueue(hotUserCommand))
{
    await DeferCommandAsync(hotUserCommand);
}

// Per-key visibility
var pendingForUser = coordinator.GetPendingCountForKey("user-123");
var opsForUser = coordinator.GetSnapshotForKey("user-123");
```

---


## 结果 - - 能力建设协调员

从 [短期成果协调员](https://github.com/scottgal/mostlylucidweb/blob/main/Mostlylucid/Helpers/Ephemeral/EphemeralResultCoordinator.cs):

```csharp
await using var coordinator = new EphemeralResultCoordinator<SessionInput, SessionResult>(
    async (input, ct) =>
    {
        var fingerprint = await ComputeFingerprintAsync(input.Events, ct);
        return new SessionResult(fingerprint, input.Events.Length);
    },
    new EphemeralOptions { MaxConcurrency = 16 });

await coordinator.EnqueueAsync(session);
coordinator.Complete();
await coordinator.DrainAsync();

// Get just the results (no metadata)
var results = coordinator.GetResults();

// Get snapshots with results + metadata
var snapshots = coordinator.GetSnapshot();

// Get base snapshots without results (privacy-safe)
var baseSnapshots = coordinator.GetBaseSnapshot();

// Filter by success/failure
var successful = coordinator.GetSuccessful();
var failed = coordinator.GetFailed();
```

---


## 货币货币管制

从 [共通货币+.cs](https://github.com/scottgal/mostlylucidweb/blob/main/Mostlylucid/Helpers/Ephemeral/ConcurrencyGates.cs):

图书馆提供两种货币管制机制

### 固定货币计算器@( @ default_)

- 后退于 `SemaphoreSlim`
- 最佳热量 @-#pathpath 性能
- 无法在运行时调整

### 可调整可调整的汇率

- 自自执行 `Queue<WaiterEntry>`
- 支助支助 `UpdateLimit()` 运行时
- 通过 `EnableDynamicConcurrency = true`

```csharp
// Dynamic concurrency adjustment
var coordinator = new EphemeralWorkCoordinator<T>(body,
    new EphemeralOptions
    {
        MaxConcurrency = 4,
        EnableDynamicConcurrency = true
    });

// Later, based on system load:
coordinator.SetMaxConcurrency(16);  // Scale up
coordinator.SetMaxConcurrency(2);   // Scale down
```

---


## 工厂模式:命名协调员

从 [依赖性喷射@. @cs](https://github.com/scottgal/mostlylucidweb/blob/main/Mostlylucid/Helpers/Ephemeral/DependencyInjection.cs):

类似 `IHttpClientFactory`, 您可以注册名为配置@:

```csharp
// Registration
services.AddEphemeralWorkCoordinator<TranslationRequest>("fast",
    async (request, ct) => await FastTranslateAsync(request, ct),
    new EphemeralOptions { MaxConcurrency = 32 });

services.AddEphemeralWorkCoordinator<TranslationRequest>("accurate",
    async (request, ct) => await AccurateTranslateAsync(request, ct),
    new EphemeralOptions { MaxConcurrency = 4 });

// Usage
public class TranslationService(IEphemeralCoordinatorFactory<TranslationRequest> factory)
{
    private readonly EphemeralWorkCoordinator<TranslationRequest> _fast =
        factory.CreateCoordinator("fast");
    private readonly EphemeralWorkCoordinator<TranslationRequest> _accurate =
        factory.CreateCoordinator("accurate");
}
```

### 工厂担保

1. **相同名称 @ = @ 相同实例** -呼叫 `CreateCoordinator("fast")` 返回同一位协调员的两倍
2. **不同的名称 @ = @ 不同实例** - `"fast"` 和 `"accurate"` 获得单独的协调员
3. **懒惰创作** - 协调员只有在第一次提出要求时才设立
4. **配置验证** - 请求未登记姓名会丢弃一个有用的错误

---


## 信号查询API

所有协调员都提供最佳的信号查询方法@:

```csharp
// Get all signals
var signals = coordinator.GetSignals();

// Filter by key (zero-allocation)
var userSignals = coordinator.GetSignalsByKey("user-123");

// Filter by time range
var recentSignals = coordinator.GetSignalsSince(DateTimeOffset.UtcNow.AddMinutes(-5));
var rangeSignals = coordinator.GetSignalsByTimeRange(from, to);

// Filter by signal name or pattern
var rateSignals = coordinator.GetSignalsByName("rate-limit");
var httpSignals = coordinator.GetSignalsByPattern("http.*");

// Check existence (short-circuits on first match)
if (coordinator.HasSignal("rate-limit"))
    await ThrottleAsync();

if (coordinator.HasSignalMatching("error.*"))
    await AlertAsync();

// Count signals efficiently (no allocation)
var totalSignals = coordinator.CountSignals();
var errorCount = coordinator.CountSignals("error");
var httpCount = coordinator.CountSignalsMatching("http.*");
```

---


## 生产优化

### 快速ID生成

从 [时长IdGenerator.cs](https://github.com/scottgal/mostlylucidweb/blob/main/Mostlylucid/Helpers/Ephemeral/EphemeralIdGenerator.cs):

```csharp
internal static class EphemeralIdGenerator
{
    private static long _counter;
    private static readonly long _processStart = Environment.TickCount64;
    private static readonly int _processId = Environment.ProcessId;

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static long NextId()
    {
        var counter = Interlocked.Increment(ref _counter);

        // Combine counter with process-unique seed
        Span<byte> buffer = stackalloc byte[24];
        BitConverter.TryWriteBytes(buffer, _processStart);
        BitConverter.TryWriteBytes(buffer.Slice(8), _processId);
        BitConverter.TryWriteBytes(buffer.Slice(16), counter);

        return unchecked((long)XxHash64.HashToUInt64(buffer));
    }
}
```

- **划拨-** ( `stackalloc`)
- **线索@ - @ 安全** ( `Interlocked.Increment`)
- **各个进程的独特性** “(”包含进程 ID)}
- **非- 顺序** @(_hash 分散反面的)#

### 内存@- @Safe Long-_Lived 操作

协调员don't 商店 `Task` 引用@- @ just counts\ :

```csharp
private int _activeTaskCount;
private readonly TaskCompletionSource _drainTcs;

// In ExecuteItemAsync:
finally
{
    // Signal drain when last task completes AND channel iteration is done
    if (Interlocked.Decrement(ref _activeTaskCount) == 0 &&
        Volatile.Read(ref _channelIterationComplete))
    {
        _drainTcs.TrySetResult();
    }
}
```

### Peró-Key 锁清理

密钥协调器自动清理闲置的 per- key semamphores @ :\ {}

```csharp
private sealed class KeyLock(SemaphoreSlim gate, int maxCount)
{
    public SemaphoreSlim Gate { get; } = gate;
    public int MaxCount { get; } = maxCount;
    public long LastUsedTicks = Environment.TickCount64;
}

// Cleanup runs periodically, removes locks idle > 60 seconds
```

---


## 完整示例

```csharp
// Program.cs
var builder = WebApplication.CreateBuilder(args);

// Named coordinators
builder.Services.AddEphemeralWorkCoordinator<TranslationRequest>("fast",
    async (req, ct) => await FastTranslateAsync(req, ct),
    new EphemeralOptions { MaxConcurrency = 16 });

// Keyed coordinator for per-user commands
builder.Services.AddEphemeralKeyedWorkCoordinator<string, UserCommand>("commands",
    cmd => cmd.UserId,
    sp =>
    {
        var handler = sp.GetRequiredService<ICommandHandler>();
        return async (cmd, ct) => await handler.HandleAsync(cmd, ct);
    },
    new EphemeralOptions
    {
        MaxConcurrency = 32,
        MaxConcurrencyPerKey = 1,
        EnableFairScheduling = true,
        CancelOnSignals = new HashSet<string> { "system-overload" }
    });

var app = builder.Build();
```

```csharp
// Controller
[ApiController]
[Route("api")]
public class WorkController : ControllerBase
{
    private readonly EphemeralWorkCoordinator<TranslationRequest> _translator;
    private readonly EphemeralKeyedWorkCoordinator<string, UserCommand> _commands;

    public WorkController(
        IEphemeralCoordinatorFactory<TranslationRequest> translationFactory,
        IEphemeralKeyedCoordinatorFactory<string, UserCommand> commandFactory)
    {
        _translator = translationFactory.CreateCoordinator("fast");
        _commands = commandFactory.CreateCoordinator("commands");
    }

    [HttpPost("translate")]
    public async Task<IActionResult> Translate([FromBody] TranslationRequest request)
    {
        await _translator.EnqueueAsync(request);
        return Ok(new { pending = _translator.PendingCount });
    }

    [HttpPost("command")]
    public IActionResult SubmitCommand([FromBody] UserCommand command)
    {
        if (!_commands.TryEnqueue(command))
            return StatusCode(429, "Too many pending commands for this user");
        return Ok();
    }

    [HttpGet("status")]
    public IActionResult GetStatus() => Ok(new
    {
        translator = new
        {
            pending = _translator.PendingCount,
            active = _translator.ActiveCount,
            completed = _translator.TotalCompleted,
            failed = _translator.TotalFailed,
            hasRateLimit = _translator.HasSignal("rate-limit")
        },
        commands = new
        {
            pending = _commands.PendingCount,
            active = _commands.ActiveCount,
            errorCount = _commands.CountSignalsMatching("error.*")
        }
    });
}
```

---


## 结论结论

我们用“:”建立了完整的执行时间库。

1. **`EphemeralForEachAsync`** - 1- 与跟踪平行处理
2. **`EphemeralWorkCoordinator`** @ -Long-活的可观察队列
3. **`EphemeralKeyedWorkCoordinator`** -=YTET -伊甸园字幕组=- 翻译:
4. **`EphemeralResultCoordinator`** -结果-捕捉变异
5. **工厂形态** - 命名的配置类似 `IHttpClientFactory`
6. **动态共同货币** -=YTET -伊甸园字幕组=- 翻译:
7. **信号基础设施** - 内建- 信号发射和查询

这些图案坐落在一个甜美的地方 :

- 可见度大于 `Parallel.ForEachAsync`
- 数据流比TPL简单
- 集成多于原声道
- 设计安全

**Fieló... 和唐' T quite forgetMS K2**

---


## 链接链接链接

- [部分#1:火和唐・'t *不错* 忘记](/blog/fire-and-dont-quite-forget-ephemeral-execution) 理论和模式
- [* 3: 时空信号部件](/blog/ephemeral-signals) 将原子变成感应网络
- [SemaphhoreSlim文件](https://learn.microsoft.com/en-us/dotnet/api/system.threading.semaphoreslim)
- [系统@ . @ treading @ MS K1 @ 通道](https://learn.microsoft.com/en-us/dotnet/core/extensions/channels)
- [TPL 数据流](https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/dataflow-task-parallel-library)
- [IHttpCliepClientFacter 模式](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/http-requests)