【发布时间】:2014-08-09 16:50:21
【问题描述】:
我的应用程序使用脚本。到目前为止,我使用 C# 编写脚本并使用 CodeDomProvider 编译它们。但是,我一直在考虑使用 NLua 分支(LuaInterface 的分支)切换到 Lua,因为它更容易编写脚本,而且我熟悉语法。
但是,我遇到了一个问题。目前,我有一个返回Task<bool> 的asynchronous 方法。它使用TaskCompletionSource 对象并返回Result。这样,我可以暂停脚本的执行,因为它会等到设置了TaskCompletionSource 对象的Result,然后才返回这个Result。
现在,有了 Lua,情况就不同了。我显然不能使用 awaitoperator,因为它是 C# 5.0 的语法,你不能在 Lua 中使用它。所以这就是为什么我要问是否有解决方法。我希望能够获得与我的旧代码(发布在这篇文章下方)相同的结果,而不必使用 awaitoperator。有人告诉我,我可以用Task.ContinueWith 做到这一点,但我对此并不熟悉,网上的例子也很枯燥。如果有人可以向我展示我的代码示例,那就太好了。
这是我的方法:
public async Task<bool> ReturnResult()
{
this.Response = new TaskCompletionSource<bool>();
return await this.Response.Task;
}
这是我在脚本中使用它的方式:
var result = await ReturnResult();
TaskCompletionSource 对象的Result 由我的代码的另一部分设置。
基本上,如果您仍然无法理解我想要实现的目标 - 一种停止执行的方法,直到代码的另一部分设置响应为止。但是,它必须是asynchronous,因为我不想让我的主线程卡住。
编辑: 尝试了 JonSkeet 的建议,代码运行时不会停止。这是完整的 Script 类。
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);
}
}
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);
}
}
只需抛出两个按钮并使用第一个按钮运行,第二个按钮设置响应。
Lua 脚本是:
result = returnResult()
log("returned " .. result)
从这里下载NLua。
【问题讨论】:
-
你能在你的 Lua 脚本中使用
Task和ContinueWith吗?另外,您能否添加设置结果的代码的另一部分? -
@YuvalItzchakov 不,但我可以注册一个涉及那些在我的 Lua 脚本中使用的方法。 Lua 脚本不能涉及 C# 语法。
-
你为什么要使用异步方法?你为什么不直接返回
this.Response.Task?等待它没有帮助。老实说,你的问题还真不清楚…… -
我有点困惑你为什么要使用
TaskCompletionSource -
@YuvalItzchakov 因为我真的不熟悉任务。我只想能够在不停止主线程的情况下停止脚本的执行,然后返回响应(仅在我的代码的另一部分设置后)。如果我不使用 await 运算符 - 代码将继续运行。
标签: c# asynchronous lua task