8000 FeatureRequest: A Top await DoStringAsync() Entrypoint · Issue #541 · NLua/NLua · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

FeatureRequest: A Top await DoStringAsync() Entrypoint #541

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
personball opened this issue Nov 27, 2024 · 1 comment
Open

FeatureRequest: A Top await DoStringAsync() Entrypoint #541

personball opened this issue Nov 27, 2024 · 1 comment

Comments

@personball
Copy link

Hi, after I search of 'async await' in issues, with #514 #295 #52

I know how to do a callback when lua invoke a async C# method with ContinueWith.

But, it is really a 'fire and forgot' invocation. The call stack will not back to the top caller.

How can I do a real one await when invoking DoString() ?

Here is codes reproduce it:

        public async Task<(string?, string?)> CreateNextProjectTaskAsync(ProjectTask upstream, string nextTaskType)
        {
            await Task.Delay(1000);
            return (upstream.TaskName, nextTaskType);
        }
        public void CreateNextTask(ProjectTask upstream, string nextTaskType, LuaFunction? callback = null)
        {
            CreateNextProjectTaskAsync(upstream, nextTaskType).ContinueWith(t =>
            {
                var res = t.Result;
                callback?.Call(res.Item1, res.Item2);
            });
        }

        [Fact]
        public async Task HandleTaskFinished()
        {
            var action =
@"
import 'System'
m:CreateNextTask(task,'Test',function(res1,res2)
    print(res1)
    x=res1
    print(res2)
    y=res1
end)
";
            using var lua = new Lua();
            lua.State.Encoding = Encoding.UTF8;
            lua.LoadCLRPackage();
            lua["m"] = this;
            lua["task"] = new ProjectTask(Guid.NewGuid())
            {
                TaskName = "Test"
            };
            var actionResults = lua.DoString(action);
            var x = lua["x"]; //null!! This line run before lua callback!
            //x.ShouldBe("Test");
            var y = lua["y"];
            //y.ShouldBe("Test");

            await Task.Delay(1000);//thread switch to callback invoke

            lua.State.Status.ShouldBe(KeraLua.LuaStatus.OK);

        }

ProjectTask could be any class with a Guid Id and string TaskName.

@personball
Copy link
Author

And now, I can use TaskCompletionSource to do some workaround...

  private TaskCompletionSource _taskCompletionSource = new(); // one time per await
...
  public void CreateNextTask(ProjectTask upstream, string nextTaskType, LuaFunction? callback = null)
  {
      CreateNextProjectTaskAsync(upstream, nextTaskType).ContinueWith(t =>
      {
          var res = t.Result;

          callback?.Call(res.Item1, res.Item2);

          _taskCompletionSource.SetResult();
      });
  }

 [Fact]
 public async Task HandleTaskFinished()
 {
  ...
  var actionResults = lua.DoString(action);
 
 await _taskCompletionSource.Task;// wait until _taskCompletionSource.SetResult(); called.

  var x = lua["x"]; // Test
  x.ShouldBe("Test");
  var y = lua["y"]; // Test
  y.ShouldBe("Test");
   
  lua.State.Status.ShouldBe(KeraLua.LuaStatus.OK);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant
0