use*_*229 1 c# lua asynchronous task
我的应用程序使用脚本。到目前为止,我已经将 C# 用于脚本并使用CodeDomProvider. 但是,我一直在考虑使用NLuafork( 的 fork LuaInterface)切换到 Lua ,因为编写脚本要容易得多,而且我熟悉语法。
但是,我面临一个问题。目前,我有一个asynchronous方法可以返回一个Task<bool>. 它使用一个TaskCompletionSource对象并返回它的Result. 这样一来,我可以阻止脚本的执行,因为这里等到Result了的TaskCompletionSource目标已定,然后才返回此Result。
现在,有了 Lua - 它是不同的。我显然不能使用await运算符,因为它是 C# 5.0 的语法,而你不能在 Lua 中使用它。所以这就是为什么我要问是否有解决方法。我希望能够获得与我的旧代码(发布在这篇文章下方)相同的结果,而无需使用await运算符。有人告诉我,我可以用 来做到这一点Task.ContinueWith,但我不熟悉这个,而且网上的例子很乏味。如果有人可以用我的代码向我展示一个示例,那就太好了。
这是我的方法:
public async Task<bool> ReturnResult()
{
this.Response = new TaskCompletionSource<bool>();
return await this.Response.Task;
}
Run Code Online (Sandbox Code Playgroud)
这是我在脚本中使用它的方式:
var result = await ReturnResult();
Run Code Online (Sandbox Code Playgroud)
在Result该的TaskCompletionSource目标是通过我的代码另一部分设置。
基本上,如果您仍然无法理解我想要实现的目标 - 一种停止执行的方法,直到代码的另一部分设置了响应。但是,它必须是asynchronous,因为我不希望我的主线程卡住。
编辑:尝试了 JonSkeet 的建议,代码直接运行而没有停止。这是完整的脚本类。
public class Script
{
private Lua Lua { get; set; }
private TaskCompletionSource<bool> Response { get; set; }
public Script()
{
this.Lua = new Lua();
}
public void Run()
{
this.Lua.RegisterFunction("log", this, typeof(Script).GetMethod("Log"));
this.Lua.RegisterFunction("returnResult", this, typeof(Script).GetMethod("ReturnResult"));
this.Lua.DoFile(@"C:\test.lua");
}
public void SetResponse(bool response)
{
this.Response.SetResult(response);
}
public Task<bool> ReturnResult()
{
this.Response = new TaskCompletionSource<bool>();
return this.Response.Task;
}
public void Log(string text)
{
MessageBox.Show(text);
}
}
Run Code Online (Sandbox Code Playgroud)
Form1的代码如下:
public partial class Form1 : Form
{
private Script Script { get; set; }
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
this.Script = new Script();
this.Script.Run();
}
private void button2_Click(object sender, EventArgs e)
{
this.Script.SetResponse(true);
}
}
Run Code Online (Sandbox Code Playgroud)
只需扔两个按钮并使用第一个按钮运行,第二个按钮设置响应。
Lua 脚本是:
result = returnResult()
log("returned " .. result)
Run Code Online (Sandbox Code Playgroud)
从这里下载NLua。
好的,正如您现在声称这与 Lua 无关,以下是您将如何在 C# 中调用该方法,然后仅在任务完成时记录:
Task<bool> task = ReturnResult();
task.ContinueWith(t => Log("Returned " + t.Result));
Run Code Online (Sandbox Code Playgroud)
这根本不会停止执行 - 它只是说当从ReturnResult完成返回的任务时,它应该调用日志记录代码。
对于生产代码,您可能想要检查任务是否出现故障等。有一些重载ContinueWith允许您指定在哪种情况下要运行延续(仅在成功时,仅在故障时等),并且您可以添加多个延续。但是为了让您继续前进,以上内容可能已经足够了。