Skip to content

Instantly share code, notes, and snippets.

@djeikyb
Last active March 1, 2024 18:54
Show Gist options
  • Save djeikyb/da978cfbfcde5b7ec1dff6eee5004f4a to your computer and use it in GitHub Desktop.
Save djeikyb/da978cfbfcde5b7ec1dff6eee5004f4a to your computer and use it in GitHub Desktop.
How to cancel a long running native function — from c# — with a CancellationToken!
using System.Runtime.InteropServices;
using System.Threading;
[StructLayout(LayoutKind.Sequential)]
internal struct InteropCancellationToken
{
public InteropCancellationToken(CancellationToken ct)
{
IsCancellationRequested = () => ct.IsCancellationRequested;
}
// ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable
private IsCancellationRequestedCallback IsCancellationRequested;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate bool IsCancellationRequestedCallback();
}
public class NativeFunctions
{
public static int ParseHugeFile(CancellationToken ct = default)
{
return parse_huge_file(new InteropCancellationToken(ct));
}
[DllImport("someNativeCode", EntryPoint = "parse_huge_file")]
private static extern int parse_huge_file(InteropCancellationToken ct);
}
extern "C" {
typedef struct CancellationToken {
bool (*IsCancellationRequested)();
} CancellationToken;
int parse_huge_file(CancellationToken ct);
}
int parse_huge_file(CancellationToken ct) {
while (!ct.IsCancellationRequested()) {
// ...
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment