给出有限的代码执行时间



我在一个看起来像这样的应用中有一系列代码行:

string botMessage = chatterBotSession.Think(input);

它正在查询聊天机器人服务,并将响应存储在botMessage中。但是,有时候,聊天机器人可能需要太长时间才能想到回应。

有没有一种方法可以像正常情况一样运行代码,但是如果它在一秒钟内未完成,然后运行一些处理程序,可以提醒用户服务时间太长?

喜欢,通常我可能会这样做:

string botMessage = chatterBotSession.Think(input);
Console.WriteLine("The bot responded with: " + botMessage);

但是,如果机器人速度慢,则第二行不会执行(足够快)。我如何将机器人的"思考"时间限制为一秒钟,并在完成后立即运行其余的代码(通常会运行),如果它成功或运行单独的代码,以显示错误消息(如果它)显示出错误消息。尚未完成。

您可以将机器人的服务调用包装在任务中。运行调用并等待预定的时间。看起来像这样

static void Main(string[] args)
{
    var task = Task.Run(() => chatterBotSession.Think(input));
    if (task.Wait(1000))
    {
        Console.WriteLine(task.Result);
    }
    else
    {
        Console.WriteLine("Couldn't get an answer in a timely manner");
    }
    Console.ReadLine();
}

通过在超时使用CancellationTokenSource时限制任务执行非常容易:

var cancellationToken = new CancellationTokenSource();
var task = chatterBotSession.Think(cancellationToken.Token);
cancellationToken.CancelAfter(TimeSpan.FromMilliseconds(1000)); // cancel after 1sec
await task;

Think方法中,您应该将呼叫添加到CancellationToken.ThrowIfCancellationRequested

调用bot:

static void Main(string[] args)
{
    TalkingBot bot = new TalkingBot();
    try
    {
        Console.WriteLine("Thinking started...");
        Console.WriteLine(bot.Think("Some input...", 2000));
    }
    catch (Exception ex)
    {
        Console.WriteLine("Error: {0}", ex.Message);
    }
    Console.ReadLine();
}

和bot本身:

class TalkingBot
{
    string input = null;
    int timeout = 0;
    string asyncThnikResult = null;
    public string Think(string input, int timeout)
    {
        DateTime timeLimit = DateTime.Now.AddMilliseconds(timeout);
        this.input  = input;
        this.timeout = timeout;
        System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(AsyncThnik));
        thread.Start();
        //wait for result, in this case 
        while (string.IsNullOrEmpty(asyncThnikResult))
        {
            if (timeLimit <= DateTime.Now)
            {
                throw new Exception("Timeout occured!");
            }
            System.Threading.Thread.Sleep(10);
        }
        //return result...
        return this.asyncThnikResult;
    }
    /// <summary>
    /// Do your thing async...
    /// </summary>
    void AsyncThnik()
    {
        string temp = "This value will never be returned due to timeout limit...";
        System.Threading.Thread.Sleep(timeout + 1000);  //add second to produce timeout...
        this.asyncThnikResult = temp;
    }
}

最新更新