NetCats
Structured, effectful concurrency for modern .NET.
Inspiration
Modern applications are increasingly concurrent, asynchronous, and distributed, but most .NET code still manages those concerns through loosely connected Task instances, cancellation tokens, exception handlers, and manually coordinated cleanup.
That approach works until the application becomes complicated.
Background operations outlive their owners. Cancellation propagates inconsistently. Exceptions disappear inside detached tasks. Resources must be released across success, failure, and interruption. Developers end up reasoning about the order in which callbacks happen rather than describing the lifetime and structure of the computation itself.
The Scala ecosystem addresses these problems through Cats Effect, which treats asynchronous work, resource ownership, cancellation, and concurrency as parts of a coherent effect system.
NetCats began with the question: what would those ideas look like if they were rebuilt specifically for modern .NET and idiomatic C#?
The objective is not to disguise Scala as C#. It is to provide .NET developers with a practical model for structured, composable effects while respecting the language, runtime, and conventions they already use.
What it does
NetCats is a .NET reimplementation of the core ideas behind Cats Effect.
It provides abstractions for representing effectful computations, running them as managed fibers, composing them into larger programs, and controlling their lifetimes explicitly.
Instead of immediately starting work and returning an unstructured Task, a NetCats program describes a computation. That computation can then be transformed, combined, started, cancelled, supervised, retried, or executed by the runtime.
This makes relationships between operations visible.
A parent computation can own child fibers. A resource can remain valid for exactly the lifetime of the work that uses it. Cancellation can flow through the computation tree. Cleanup can happen predictably whether the operation succeeds, fails, or is interrupted.
NetCats is designed to support applications where lifecycle correctness matters:
- Long-running services
- Distributed workers
- Streaming APIs
- Background processing
- Resource-sensitive applications
- Concurrent workflows
- Systems with complex cancellation behaviour
- Applications that need deterministic cleanup
The result is a model where asynchronous behaviour is represented as data before it becomes execution.
Why structured effects
Task is an effective representation of an operation already in progress, but it does not by itself describe who owns that operation, how long it should live, or what should happen to its children when it ends.
Those decisions are normally spread across application code.
A task might be stored in a collection, paired with a cancellation token, wrapped in a try/finally, observed by a continuation, and cleaned up by a hosted service. Each individual mechanism is valid, but their relationship exists primarily in the developer’s head.
NetCats brings those relationships into the program structure.
Fibers represent running computations with explicit handles for joining or cancellation. Resource operations tie acquisition and release to a defined scope. Combinators allow behaviour such as sequencing, parallelism, recovery, racing, retrying, and cancellation to be expressed without manually assembling the underlying control flow each time.
This does not remove complexity from concurrent software. It makes that complexity explicit, composable, and testable.
How it works
At the centre of NetCats is an effect value that describes a computation without immediately executing it.
Effects can be created from synchronous or asynchronous operations and composed using functional transformations. The runtime interprets the resulting description and performs the work.
When an effect is started concurrently, NetCats represents it as a fiber. The fiber exposes structured operations for observing completion and requesting cancellation rather than becoming an anonymous background task.
Resources are represented as scoped computations. Acquisition, use, and release remain connected, ensuring that cleanup occurs across normal completion, errors, and cancellation.
The model separates three concerns that are often mixed together in ordinary asynchronous code:
- Description — what the program should do.
- Composition — how operations relate to one another.
- Execution — when and under whose lifetime the work runs.
That separation enables developers to build larger concurrent programs from smaller operations while retaining control over failure, interruption, and cleanup.
Built for .NET
NetCats is inspired by Cats Effect, but it is implemented for the .NET runtime rather than treated as a direct syntax translation.
C# has its own asynchronous conventions, type-system constraints, cancellation model, exception behaviour, and runtime primitives. NetCats works with those realities.
The project uses modern C# and .NET facilities while exposing a functional model that remains usable from normal application code.
The design must bridge two expectations:
- Functional programmers expect effects to remain composable, lawful, and explicit.
- .NET developers expect compatibility with
Task,ValueTask,CancellationToken,IAsyncDisposable, dependency injection, and the wider runtime ecosystem.
NetCats occupies the boundary between those worlds.
Existing asynchronous .NET operations can be lifted into effects. Effectful programs can still interact with conventional libraries and infrastructure. Developers can adopt the model at the boundaries where it provides value rather than requiring an entire application to be rewritten around it.
Examples as system tests
The NetCats examples are not intended to be isolated syntax demonstrations.
Each example is designed to place the effect system under increasingly realistic pressure and demonstrate why the abstractions matter.
MutualGPU is being developed as Example 3.
MutualGPU coordinates a distributed network of GPU-capable workers. Providers connect through long-lived streams, receive tasks, process data, upload results, disconnect unexpectedly, and respond to cancellation.
That makes it an appropriate NetCats example because its core problems are lifecycle problems.
A provider session has a beginning and an end. Assigned work belongs to that session. Losing the provider must affect the work it owns. Cancellation and cleanup must remain reliable across network failures.
NetCats allows those relationships to be represented as supervised fibers and scoped resources rather than as disconnected callbacks and background tasks.
Using NetCats in a distributed system also forces the library to prove itself beyond controlled examples. The abstractions must remain understandable when applied to real networking, storage, scheduling, authentication, and failure conditions.
How Codex and GPT-5.6 were used
Codex and GPT-5.6 were used to develop both NetCats and the systems that validate it.
The work was not limited to generating implementations from predefined specifications. Codex was used to interrogate abstractions, compare API shapes, identify lifecycle ambiguities, and translate functional concepts into forms appropriate for C#.
A recurring part of the process was distinguishing superficial similarity from semantic equivalence.
An API can resemble Cats Effect while behaving differently around cancellation, resource release, error propagation, or concurrent execution. Codex helped pressure-test those boundaries by exploring failure paths and asking what each abstraction guarantees rather than only whether the happy-path syntax looks correct.
Codex was also used to design realistic examples.
During the MutualGPU planning process, it helped expose questions that directly test NetCats:
- What owns an assigned task?
- What happens when a provider disconnects?
- Where should cancellation originate?
- Which operations need persistent fibers?
- Which resources belong to a provider session?
- How should failures propagate between parent and child computations?
- Which cleanup operations must be uncancellable?
These questions turn the example applications into feedback for the library itself.
GPT-5.6 was particularly useful for maintaining context across the effect model, the .NET implementation, and the architecture of the consuming system. It could reason about the abstractions and their operational consequences together rather than treating them as unrelated coding tasks.
Challenges we encountered
One of the largest challenges is translating concepts without importing assumptions from another runtime.
Scala and C# have different type systems and different conventions for expressing higher-order abstractions. An implementation that is elegant in Scala may become awkward, misleading, or unnecessarily abstract in C#.
NetCats therefore has to preserve behaviour without demanding that users write Scala-shaped C#.
Cancellation is another major challenge.
.NET cancellation is cooperative and conventionally represented by CancellationToken. An effect system must integrate with that model while also providing structured guarantees about fibers, finalisation, and interruption. Cancellation cannot simply mean passing another token through every method; its relationship to ownership and cleanup must be defined.
Resource safety presents a similar problem.
using, await using, and try/finally work well locally, but concurrent resources may be shared across child computations or remain active for the lifetime of a fiber. NetCats must make those scopes reliable without hiding when acquisition and release actually happen.
The final challenge is API clarity.
Effect systems can easily become dominated by terminology and advanced type concepts. NetCats needs to retain the precision of the model while remaining approachable to developers familiar with ordinary async C#.
Accomplishments
We are proud that NetCats is not only an experiment in functional syntax.
It provides a practical foundation for reasoning about ownership, cancellation, failure, and cleanup in concurrent .NET applications.
We are also proud that the project is being developed alongside substantial examples rather than in isolation. MutualGPU exercises NetCats through long-lived connections, distributed workers, streaming protocols, task assignment, failure recovery, and resource-sensitive operations.
That creates a productive feedback loop:
- NetCats gives the examples a coherent concurrency model.
- The examples reveal where NetCats is unclear, incomplete, or difficult to use.
- Those discoveries improve the underlying library.
- Improved abstractions make the next example more ambitious.
The project also demonstrates that functional effects are relevant to ordinary .NET engineering problems. They are not limited to academic programs or purely functional applications. They provide a vocabulary for problems developers already face every day.
What we learned
The most important lesson is that concurrency is largely about ownership.
Starting work is easy. Determining who owns it, how long it may run, what happens when its owner fails, and who is responsible for cleanup is the difficult part.
Structured effects provide answers to those questions by making lifetime relationships part of the computation.
We also learned that faithful reimplementation does not mean literal translation.
The value of Cats Effect lies in its semantics: composability, cancellation, resource safety, and structured concurrency. Preserving those properties matters more than reproducing the exact surface syntax of the original library.
Another lesson is that examples should be adversarial.
A useful concurrency example should include cancellation, failure, nested lifetimes, resource acquisition, and operations that outlive a single request. Otherwise, it proves only that the API works under conditions where ordinary Task code was already sufficient.
Finally, we learned that effect systems become easier to understand when their benefits are demonstrated through concrete ownership problems rather than introduced only through functional terminology.
What’s next
The next stage of NetCats is to continue expanding its runtime, concurrency primitives, resource model, documentation, and practical examples.
MutualGPU will remain an important proving ground as its scheduler, provider sessions, task execution, retries, and failure handling become more sophisticated.
Future work will focus on:
- Refining fiber supervision and cancellation semantics
- Strengthening resource-safety guarantees
- Expanding concurrency and coordination primitives
- Improving interoperability with conventional .NET async APIs
- Developing clearer diagnostics for effect execution
- Adding tests for races, cancellation, and finalisation
- Producing examples that progress from introductory composition to distributed systems
- Documenting not only how each operator works, but why a developer would use it
The long-term objective is to make structured effects a practical option for .NET developers building software where asynchronous lifetimes can no longer safely remain implicit.
NetCats turns concurrency from a collection of background tasks into a program whose structure can be understood.

Log in or sign up for Devpost to join the conversation.