{"record":{"id":"2fbb42bef9738cf5","repo":"stride3d/stride","slug":"cannot-receive-out-of-micro-thread-context","errorCode":null,"errorMessage":"Cannot receive out of micro-thread context.","messagePattern":"Cannot receive out of micro-thread context\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"sources/core/Stride.Core.MicroThreading/Channel.cs","lineNumber":89,"sourceCode":"        {\n            receiver.MicroThread.ScheduleContinuation(ScheduleMode.First, receiver.Continuation);\n            throw new NotImplementedException();\n            //await Scheduler.Yield();\n        }\n        receiver.IsCompleted = true;\n        return receiver;\n    }\n\n    /// <summary>\n    /// Receives a value over the channel. If no other <see cref=\"MicroThread\"/> is sending data, the receiver will be blocked.\n    /// If someone was sending data, which of the sender or receiver continues next depends on <see cref=\"Preference\"/>.\n    /// </summary>\n    /// <returns>Awaitable data.</returns>\n    public ChannelMicroThreadAwaiter<T> Receive()\n    {\n        if (senders.Count == 0)\n        {\n            var microThread = MicroThread.Current ?? throw new Exception(\"Cannot receive out of micro-thread context.\");\n            var waitingMicroThread = ChannelMicroThreadAwaiter<T>.New(microThread);\n            receivers.Enqueue(waitingMicroThread);\n            return waitingMicroThread;\n        }\n\n        var sender = senders.Dequeue();\n        if (Preference == ChannelPreference.PreferReceiver)\n        {\n            sender.MicroThread.ScheduleContinuation(ScheduleMode.Last, sender.Continuation);\n        }\n        else if (Preference == ChannelPreference.PreferSender)\n        {\n            sender.MicroThread.ScheduleContinuation(ScheduleMode.First, sender.Continuation);\n            throw new NotImplementedException();\n            //await Scheduler.Yield();\n        }\n        sender.IsCompleted = true;\n        return sender;","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/core/Stride.Core.MicroThreading/Channel.cs#L71-L107","documentation":"Channel<T>.Receive() awaits data via a micro-thread awaiter; when no senders are pending it needs the ambient MicroThread.Current to register the receiver for wakeup. If called outside any micro-thread, the library throws, because there is no scheduler to resume the continuation.","triggerScenarios":"Calling channel.Receive() from a plain Task, thread-pool thread, main thread, or constructor instead of inside a micro-thread started via Scheduler.","commonSituations":"Calling Receive in unit tests without a scheduler; consuming a Stride channel from a background Task.Run; awaiting a channel in app startup code outside the Stride script/micro-thread system.","solutions":["Call Receive only inside code running as a micro-thread (e.g. via Scheduler.Spawn/addScript or Script component)","If you must consume from ordinary code, use a non-blocking check (senders.Count / TryReceive-style polling) or a standard concurrent queue instead","Wrap the consuming logic in a micro-thread that the scheduler runs"],"exampleFix":"// before\nTask.Run(() => value = channel.Receive());\n// after\nScheduler.Spawn(async mt => { value = await channel.Receive(); });","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"bool canReceive = MicroThread.Current != null;","tryCatchPattern":"try { value = await channel.Receive(); }\ncatch (Exception) when (MicroThread.Current == null) { /* fall back to polling or re-run in micro-thread */ }","preventionTips":["Only call Channel.Receive inside micro-thread code","Use polling/queues for cross-context consumption","Wrap consumers in Scheduler.Spawn micro-threads"],"tags":["csharp","microthreading","async","stride"],"backgroundTag":"invalid-state-transition","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}