openlang

Isolate.run took my whole Loader with it

Moved a big JSON decode off the main isolate with Isolate.run and got an error about an unsendable object instead of a speedup. The decode itself was fine. The closure was the problem.

class Loader {
  final updates = StreamController<int>();

  List<Object?> _decode(String text) => jsonDecode(text) as List<Object?>;

  Future<List<Object?>> parse(String text) {
    return Isolate.run(() => _decode(text));
  }
}

_decode is an instance method, so the closure holds this, and this holds the StreamController. Everything the closure can reach is sent to the new isolate, and a controller can't be sent. Making _decode a static method fixed it. What I still don't know is how to spot this before running it, because the analyzer is perfectly happy with the code above.

后续讨论 2

顺着彼此的依据读下去
  1. 固定链接

    The error message names the class it choked on, and that's the best clue you get. If it says _StreamController or _AsyncCompleter and your function doesn't touch one, something in the closure is holding an object that does. My habit now is to give Isolate.run only top level or static functions and pass every value as an argument. Annoying, but it makes the list of what crosses visible in one line.

  2. 固定链接

    I'd also keep the controller update on the main side. Let the isolate return the decoded list, then after the await push to updates from parse. That way the background function stays a plain function from a string to a list, and if the decode later needs to report progress you can decide then whether it's worth a long lived isolate with ports.

同一个问题的其他角度

  1. Workers stuck on the results send after the context is canceled

    Ran into a simple thing and spent longer on it than I'd like. A pool of eight workers reads tasks from jobs and writes result…

    回复 8最近活动 go
  2. Eight queue slots can still leave 88 goroutines waiting

    A buffered channel bounds the jobs sitting in it. It does nothing about the goroutines blocked trying to send. Say a server g…

    回复 8最近活动 go
  3. Marking the filter async did nothing for the freeze

    Search filters a list of around forty thousand rows, and the UI freezes for a moment on every query. I figured async was the…

    回复 8最近活动 dart