Client v5: BLE, BLE Hosting, HTTP, Jobs - Linux, MacOS, & Blazor Support! Full AOT, RX on BLE only & MANY other features! Check It Out
Jobs Releases
5.0.0 - TBD
Section titled “5.0.0 - TBD” BREAKING Enhancement
JobRegistration.Identifier removed — the job’s CLR Type is now the unique identifier. The WithIdentifier(...) fluent extension is gone. Log messages now reference JobType.FullName. Migrate by deleting .WithIdentifier("...") calls; the registration’s identity is implicit in the type you registered. BREAKING Enhancement
IJobManager.RunJobAsTask(string, CancellationToken) replaced by IJobManager.RunJob(Type jobType, CancellationToken). The job is looked up by its registered CLR type and runs normally (inline). Migrate mgr.RunJobAsTask("MyJob") → mgr.RunJob(typeof(MyJob)).IJobManager.RunTask(...) removed, along with the RunJob(..., runAsTask: true) overload and the protected RunAsTask platform template. These wrapped runs in iOS BeginBackgroundTask / Android partial wake-locks for extended execution, which caused a number of hard-to-diagnose native issues (crashes on overrun, disposed completions). Jobs now always run normally. Migrate RunJob(typeof(MyJob), runAsTask: true) → RunJob(typeof(MyJob)); for ad-hoc work previously run via RunTask, register it as a normal IJob and call RunJob, or just await your own method. Enhancement Android
The
WAKE_LOCK permission is no longer used or needed by Shiny.Jobs — the only consumer was the now-removed wake-lock task wrapping. Feature
Plain .NET (base TFM) support added —
Shiny.Jobs now ships an in-process managed JobManager for Linux, macOS, Blazor WebAssembly, console, and any other non-iOS/Android .NET host. Driven by a recurring timer (default 30s, configurable via JobManager.Interval, min 15s / max 5m). Honours the same BatteryNotLow, DeviceCharging, and RequiredInternetAccess constraints as the native platforms and auto-registers a default JSON filesystem repository under {LocalApplicationData}/Shiny. Jobs only execute while the host process is alive — there is no OS-level scheduler on these targets. Feature Windows
Windows support — COM-activated in-process background tasks. Call
ShinyJobsBackgroundTask.RegisterComServer() once in your App constructor before any trigger registration, and declare a matching windows.comServer extension in your appx manifest. Feature
Blazor WebAssembly (Web) support added via the base
Shiny.Jobs package (no separate meta-package). Reference Shiny.Jobs directly and bring in Shiny.Core.Blazor for IBattery/IConnectivity; optionally add Shiny.Extensions.Stores.Web to persist job state to browser localStorage instead of the default filesystem repository. The in-process scheduler runs while the tab is open. Note: Service Worker / Periodic Background Sync cannot invoke C# jobs because the SW has no access to the Blazor WASM runtime — for background HTTP specifically, use Shiny.Net.Http.Blazor instead.Rx removed from
Shiny.Jobs. The internal driver and lifecycle task no longer depend on System.Reactive. There were no public observable members on IJobManager; this is mostly a transitive dependency cleanup. Fix iOS
Fixed a native
SIGSEGV crash when a BGTaskScheduler job ran past its allotted time. The expiration handler now marks the task complete immediately (instead of only after every job finished), BGTask.SetTaskCompleted is guarded to fire exactly once, and the per-run CancellationTokenSource is no longer disposed while iOS still holds a native reference to its cancel handler. Fix iOS
JobManager.Start() no longer iterates an empty registration set on iOS/Mac Catalyst — the Apple JobManager constructor now receives the JobRegistrar directly, so background task scheduling via BGTaskScheduler happens against the real registered jobs at host boot. Fix Android
JobManager.Start() no longer iterates an empty registration set on Android — the Android JobManager constructor now receives the JobRegistrar directly, so WorkManager periodic categories are enqueued with the real registered jobs at host boot. Fix Windows
JobManager.Start() no longer iterates an empty registration set on Windows — the Windows JobManager constructor now receives the JobRegistrar directly, so the COM-activated background task categories are registered with the real jobs at host boot. Enhancement
AbstractJobManager now treats JobRegistrar.Jobs as the single source of truth. The duplicate internal registrations dictionary and the AddRegistrations lazy-hydration method are gone, and GetJobs() / GetJobsByCategory() read straight from the registrar. JobLifecycleTask no longer needs the registrar injected. BREAKING Enhancement
Removed the empty
Shiny.Jobs.Blazor meta-package. It contained no code — just project references. Consumers should reference Shiny.Jobs + Shiny.Core.Blazor (and optionally Shiny.Extensions.Stores.Web) directly. BREAKING Enhancement
Restructured job scheduling API - Register/Cancel replaced with explicit RegisterPlatformJob, UnRegisterPlatformJob, UnRegisterAllPlatformJobs, and GetPlatformJobs
Enhancement
JobLifecycleTask now manages registered jobs via DI and re-registers on startup
Enhancement Android
Improved ShinyJobWorker implementation
4.0.1 - March 26, 2026
Section titled “4.0.1 - March 26, 2026” Fix Android
AndroidX version pins
4.0.0 - March 26, 2026
Section titled “4.0.0 - March 26, 2026” Fix Android
Successful jobs that run too long often tend to have Android completion already disposed
3.1.2 - November 7, 2023
Section titled “3.1.2 - November 7, 2023” Fix
Base Job was not calculating runtime difference properly
3.0.0 - September 5, 2023
Section titled “3.0.0 - September 5, 2023” BREAKING iOS
We no longer support the background fetch style (old) job management - only bgtasks will be used going forward