RAN013 Signal write or Pump on a thread-pool callback
warning RAN013: temperature.Value <- 25 runs on a thread-pool thread; a write off the graph's owning thread raises under ThreadAffinity.Guarded.
Cause. Under the default Guarded affinity, a signal write or Graph.Pump on a thread other than the graph's owner raises ... ran on thread N, but this graph is owned by thread M. The rule reports a write or Pump in a delegate handed to Task.Run, Task.Factory.StartNew, ThreadPool.QueueUserWorkItem, a new Thread, Parallel.For, Parallel.ForEach or a Timer. AsyncSource.Settle and Fail are not reported: an off-thread settle waits in the graph's inbox. A write to a signal, async source or memo that the delegate constructs over a graph the same delegate constructs, or creates in that graph's Run, a write inside that graph's Run, and a Pump of that graph run on the graph's own thread and are not reported. Parallel.Invoke and ContinueWith count as starters too.
Fix. Hand the write to graph.Dispatch. A graph built with ThreadAffinity.Unchecked, or a host that guarantees one thread, suppresses the finding with its reason.
Triggers
module Example
open System.Threading.Tasks
open Ranvier
let report (temperature: Signal<int>) = Task.Run (fun () -> temperature.Value <- 25)
Fixed
module Example
open System.Threading.Tasks
open Ranvier
let report (graph: Graph) (temperature: Signal<int>) =
Task.Run (fun () -> graph.Dispatch (fun () -> temperature.Value <- 25))
Suppression. // fsharpanalyzer: ignore-line RAN013, with the reason on the line before.