---
title: "Cancel an OCR operation in C#"
url: https://recursiveai.org/oneocr/cookbook/cancel-ocr-operation/
description: "Cancel asynchronous image OCR in C# with a CancellationToken, handle OperationCanceledException, and run a local example with a sample image."
version: "1.0.0"
---

# Cancel an OCR operation in C#

**OneOcr** is a free, open-source OCR library for .NET from Recursive AI. MIT or Apache-2.0, no native dependencies.

[NuGet](https://www.nuget.org/packages/RecursiveAI.OneOcr) · [GitHub](https://github.com/recursive-ai-oss/oneocr-csharp) · [Docs](https://recursiveai.org/oneocr/docs/) · [Download example (.zip)](https://recursiveai.org/oneocr/cookbook/cancel-ocr-operation/cancel-ocr-operation.zip)

Cancel asynchronous OCR with a token. `hello.png` in the zip contains “HELLO OCR”.

```shell
dotnet add package RecursiveAI.OneOcr
```

Requires [.NET 10](https://dotnet.microsoft.com/download/dotnet/10.0) (net10.0); .NET 9 and earlier aren’t supported.

```csharp
using OneImage;
using OneOcr;

var engine = OcrEngine.LoadBundled();
var image = Image.Load("hello.png");
using var cts = new
    CancellationTokenSource(30_000);
var task = image.ToTextAsync(
    engine, null, cts.Token);
cts.Cancel();
try { Console.WriteLine(await task); }
catch (OperationCanceledException)
{
    Console.WriteLine("OCR cancelled.");
}
```

```text
OCR cancelled.
```

`hello.png` is the generated sample in the zip: a white image with the black text “HELLO OCR”. The program starts a task with a 30-second cancellation deadline, then calls `Cancel()` immediately to demonstrate the cancellation branch. Keep the image alive until the awaited task completes. Cancellation throws `OperationCanceledException`; other OCR or input errors are not swallowed by this catch.

Cancellation can race completion, so a fast machine may print the recognized text instead.

Unzip [the example](https://recursiveai.org/oneocr/cookbook/cancel-ocr-operation/cancel-ocr-operation.zip), then `dotnet run`.

## Variations

**Reject work that is already cancelled.** This complete snippet uses the same sample image.

```csharp
using OneImage;
using OneOcr;
var engine = OcrEngine.LoadBundled();
var image = Image.Load("hello.png");
using var cts = new CancellationTokenSource();
cts.Cancel();
try { await image.ToTextAsync(engine, null, cts.Token); }
catch (OperationCanceledException)
{
    Console.WriteLine("OCR cancelled before recognition.");
}
```

```text
OCR cancelled before recognition.
```

## Related recipes

- [Extract text from an image](https://recursiveai.org/oneocr/cookbook/extract-text-from-image/)
- [Read OCR page JSON](https://recursiveai.org/oneocr/cookbook/page-json/)

## The short answer

Pass a `CancellationToken` to `image.ToTextAsync`, request cancellation through its `CancellationTokenSource`, and await the task inside a catch for `OperationCanceledException`. OneOcr checks cancellation cooperatively; cancelling is a request to stop, not an instruction to terminate a thread immediately.

## How do you cancel OCR in C#?

Create a source owned by the calling operation, pass its token to OCR, and call `Cancel()` when that operation is no longer wanted. In an application, the trigger can be a Cancel button, a closed view or an aborted request. The sample calls it directly so the behavior can be reproduced without a user interface.

OneOcr’s [threading documentation](https://recursiveai.org/oneocr/docs/overview/) says that local calls check the token between pages and between lines and throw `OperationCanceledException`. The async twin runs the same local code on a thread-pool thread. Awaiting it lets the caller observe completion or cancellation without blocking the calling thread on recognition.

Keep the source and the image alive while that work runs. Do not dispose of input resources just because cancellation was requested; await the task first. Cancellation and completion can race. If recognition finishes before a later cancellation request is observed, the operation may already have returned successfully. Handle that as completion rather than assuming every click must produce an exception.

## How do you use a cancellation token with a timeout?

The source constructor in the program requests cancellation after 30 seconds. The immediate `Cancel()` is included solely to exercise the handler; leave out that demonstration call for a deadline-only operation. The timer requests cancellation on the same token that the OCR call receives.

Cooperative cancellation does not promise that the task stops at the exact deadline. The local OCR code observes the token at its documented checkpoints. Put model loading and image loading outside your expectations for the OCR token: the example constructs both before starting the token-bounded task.

A timeout is not a reason to return invented text or a partial result as if recognition succeeded. The handler in this recipe prints a cancellation message. Your application can report that status to the caller and offer a retry, but should distinguish it from a completed empty-text result and from an invalid input file.

## What happens if a cancellation token is already cancelled?

The variation cancels the source before calling OCR. Awaiting the operation reaches the same cancellation handler, without a normal recognition result. This is useful when a queued job becomes unwanted before it starts. It also demonstrates that the cancellation path does not require a partially recognized document.

Create a new source for a new operation rather than reusing the cancelled token as though it were fresh. Dispose of each source after its operation completes. If several local calls intentionally share one source, a request on it applies to every call observing that token.

Cancellation does not change the recognition algorithm or improve its output. The library documents the async twin as running the same code and producing byte-identical results to the synchronous call when it completes. Choose async and cancellation for control of the operation; choose recognition settings separately for the document you need to read.
