异步方法返回类型

本文关键字:返回类型 异步方法 | 更新日期: 2023-09-27 17:49:52

这是我想要实现的脚本(使用CodeDomProvider编译和运行)。

AddText("Testing. Press yes to continue.");
var answer = SendYesNo();
if (answer)
{
    AddText("Good.");
    SendOk();
} 
else
{
    AddText("Not good.");
    SendOk();
}

。我希望SendYesNo使用AutoResetEvent,这样它就会停止脚本执行,直到给出响应。一旦设置了响应,自动重置事件也将被设置,因此它将继续执行并返回响应。例如,到目前为止我写的:

public bool SendYesNo()
    {
        this.waitHandle = new AutoResetEvent(false);
        this.waitHandle.WaitOne();
        return this.Selection;
    }

设置选区,使用:

public void SetSelection(bool selection)
    {
        this.Selection = selection;
        this.waitHandle.Set();
    }

然而,它不起作用(设置响应后什么都没有发生),整个程序卡住了。没有什么功能。为什么?我想我必须使用异步,但我不确定如何。此外,我应该使用自定义eventandler吗?

谢谢。

异步方法返回类型

也许如果我理解了,那么你需要这样的东西。

private Task<bool> SendYesNo()
{
    if (Yes)
    {
        return true;
    }
    else
    {
        return false;
    }
}

AddText("Testing. Press yes to continue.");
var answer = await SendYesNo();
if (answer)
{
    AddText("Good.");
    SendOk();
} 
else
{
    AddText("Not good.");
    SendOk();
}

这实际上比我想象的要简单得多。框架提供了一个TaskCompletionSource<T>类型,它可以做你想做的事情。

class NpcScript {
    TaskCompletionSource<bool> response = new TaskCompletionSource<bool> ();
    public void SetResponse(bool value) {
        response.SetResult (value);
    }
    async Task<bool> SendYesNo() {
        return await response.Task;
    }

    public async Task Perform() {
        AddText("Testing. Press yes to continue.");
        var answer = await SendYesNo();
        if (answer)
        {
            AddText("Good.");
            SendOk();
        } 
        else
        {
            AddText("Not good.");
            SendOk();
        }
    }
}
编辑:

你也应该从一些异步上下文中调用execute和await。例如,假设我创建了一个任务来处理Perform,另一个任务等待用户输入,我可以启动两个任务,但要等待它们全部完成后才能继续在线程中执行。

var script = new NpcScript();
var taskPerform = new Task(async () => {
    await script.Perform();
});
taskPerform.Start();
var taskInput = new Task(() =>
    //get user input here
    script.SetResponse (inp);
});
taskInput.Start();
Task.WaitAll(new Task[] { taskPerform, taskInput });