使用ContinueWith替代await运算符

我的应用程序使用脚本。迄今为止,我已经使用C#编写脚本,并使用CodeDomProvider编译它们。但是,我正在考虑切换到Lua,使用NLua分支(LuaInterface的分支),因为它更容易编写脚本,而且我熟悉语法。

但是,我面临一个问题。目前,我有一个返回Task<bool>异步方法。它使用TaskCompletionSource对象,并返回它的Result。这样,我就可以停止脚本的执行,因为它等待TaskCompletionSource对象的Result设置,然后仅返回此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;
}

这是我在脚本中使用它的方式:

var result = await ReturnResult();

TaskCompletionSource对象的Result是由我的代码的另一部分设置的。

基本上,如果您仍然无法理解我要达到的目标-一个方法,在另一部分代码设置响应之前暂停其执行。但是,它必须是“异步的”,因为我不希望我的主线程被卡住。

编辑:尝试了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 Form1Form
{
    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

点赞
用户22656
用户22656

好的,既然你现在声称这与 Lua 无关,那么这是在 C# 中调用该方法并且仅在任务完成后记录日志的方法:

Task<bool> task = ReturnResult();
task.ContinueWith(t => Log("Returned " + t.Result));

不会 完全停止执行 - 它只是说当从 ReturnResult 返回的任务完成时,它应该调用记录代码。

对于生产代码,您可能希望检查任务是否发生故障等。有许多 ContinueWith 的重载,您可以在这些重载中指定您想要运行继续程序的情况(仅在成功时运行、仅在故障时运行等),而且您可以添加多个继续程序。但是,为了让您开始工作,上面的代码可能已经足够了。

2014-08-09 08:50:21