Open FrankBakkerNl opened 8 years ago
Just curious; what happens if you do await Task.Delay(10000);
instead of Thread.Sleep(10000);
?
I was just trying exactly that,
var code = @"
System.Console.WriteLine(""Script Start"" );
await System.Threading.Tasks.Task.Delay(1000);
System.Console.WriteLine(""Script End"" );";
var script = CSharpScript.EvaluateAsync(code);
Console.WriteLine("EvaluateAsync Done");
Console.WriteLine("Task Completed");
Console.ReadLine();
This does produce the result
Script Start
EvaluateAsync Done
Task Completed
Script End
So EvaluateAsync does not execute the whole script async, it just allows you to use await inside the script. This probably makes sense, but was not what I expected
Oh, so it did work? Huh.
@FrankBakkerNl You can get your desired behavior by making Script.EvaluateAsync
an inner task, similar to what the Interactive Editor does here https://github.com/dotnet/roslyn/blob/master/src/Interactive/Features/Interactive/Core/InteractiveHost.Service.cs#L816
@tenor: This indeed is what I ended up doing and works like expected.
I can see how this behavior is By Design, but it is somewhat confusing to have an ..Async method that does not return immediately. I think it would be good to make this clear in the final API documentation
Yes it is. To be fair the call awaits on the execution.
It seems like the default TaskScheduler causes this by inlining awaits aggressively. A custom TaskScheduler that uses a new thread per await will have the expected behavior.
So now I am not sure whether this means it actually is by design in which case I can of course close this issue.
I think there might be an issue, but probably not super important. The name .RunAsync
suggests to me that this will always return immediately if you don't await.
@tmat Can you provide some input?
From another point of view, this code
var code = @"
System.Console.WriteLine("">Script Start"" );
System.Threading.Thread.Sleep(1000);
System.Console.WriteLine("">After Sleep"" );
await System.Threading.Tasks.Task.Delay(1000);
System.Console.WriteLine("">After await delay"" );
";
var task1 = CSharpScript.EvaluateAsync(code);
Console.WriteLine("Async call Done");
task1.Wait();
Console.WriteLine("Task Completed");
Produces the same output as when the same code is copied into a lambda.
Func<Task> FuncAsync = async () =>
{
System.Console.WriteLine(">Script Start");
System.Threading.Thread.Sleep(1000);
System.Console.WriteLine(">After Sleep");
await System.Threading.Tasks.Task.Delay(1000);
System.Console.WriteLine(">After await delay");
};
var task2 = FuncAsync();
Console.WriteLine("Async call Done");
task2.Wait();
Console.WriteLine("Task Completed");
Console.ReadLine();
output:
>Script Start
>After Sleep
Async call Done
>After await delay
Task Completed
When looking at the script an a 'normal' async method the current behavior is exactly what is expected. When however you are not aware of the fact that the script itself can be asyc, you might expect the whole script to be run async when calling EvaluateAsync() (Like I did)
Is there a recommended way to run the script async? I want to get Task<ScriptState>
before the script completes its execution to monitor its activity, but with current implementation I don't see how can I manage it.
I want to start long-running task and monitor if it is executing or completed or threw exception. To do this I make the following:
Task<ScriptState> state = null;
ThreadPool.QueueUserWorkItem(_ => {
state = CSharpScript.RunAsync<int>(script, opt);
//I can get the state only when script completes execution and while script is execusing
//state is always null
});
//Monitor state in another place
while (!state.IsCompleted)
{
//do something
}
Is it possible to get the Task<ScriptState>
before scripts completes the execution? Script is similar to mentioned above:
while(true)
{
//do something
Thread.Sleep(1000);
}
This hasn't been updated for over two and a half years. Is is still a problem?
This hasn't been updated for over two and a half years. Is is still a problem?
Yes, this is still an issue as of v3.6.0 of Microsoft.CodeAnalysis.CSharp.Scripting.
Still an issue 10 years later 👀
@MaxenceMouchard This is on the backlog.
I expected CSharpScript.EvaluateAsync(string code) to return a Task before the script has completed execution and that the task would then complete when the script has completed. This would be especially useful for potentially rong running scripts. This however is not how it currently works in version 1.1.0-rc1-20151109-01.
when I run the following
It produces the output