dlr
dlr copied to clipboard
Strange iterator behavior with async code
I'm getting a weird error when trying to run a modified version of Scenario_ExecuteFile_Push. Here is my code:
public static class Scenarios {
static async Task Main() {
await Scenario_ExecuteFile_Push();
}
public class MyHostObjectModel {
public Func<IEnumerable<string>> GetUserCommands = default!;
}
private static ScriptRuntime CreateScriptRuntime()
{
var setup = new ScriptRuntimeSetup();
setup.LanguageSetups.Add(IronPython.Hosting.Python.CreateLanguageSetup(null));
var runtime = new ScriptRuntime(setup);
return runtime;
}
public static async Task Scenario_ExecuteFile_Push() {
var hostOm = new MyHostObjectModel();
var runtime = CreateScriptRuntime();
runtime.Globals.SetVariable("App", hostOm);
runtime.ExecuteFile("register_user_commands.py");
foreach (var str in hostOm.GetUserCommands())
{
// await Task.Delay(100);
Console.WriteLine(str);
}
}
}
Here is my register_user_commands.py:
import App
def fun():
yield 'does'
yield 'this'
yield 'work'
App.GetUserCommands = fun
Without the Task.Delay, (aka when run synchronously) this prints to the console:
does
this
work
But with the Task.Delay uncommented I get:
does
this
work
Unhandled exception. System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')
at System.Collections.Generic.List`1.RemoveAt(Int32 index)
at Microsoft.Scripting.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.LightLambda.Run1[T0,TRet](T0 arg0)
at IronPython.Runtime.PythonGenerator.GetNext()
at IronPython.Runtime.PythonGenerator.MoveNextWorker()
at IronPython.Runtime.PythonGenerator.System.Collections.IEnumerator.MoveNext()
at IronPython.Runtime.IEnumeratorOfTWrapper`1.MoveNext()
at dlr_playground.Scenarios.Scenario_ExecuteFile_Push() in [...]Program.cs:line 39
at dlr_playground.Scenarios.Main() in [...]Program.cs:line 17
at dlr_playground.Scenarios.<Main>()