【问题标题】:C# async/await issue [closed]C#异步/等待问题[关闭]
【发布时间】:2020-01-03 13:45:33
【问题描述】:

抱歉问题的标题,我不确定应该是什么。

我有这个方法:

public async Task Instagram(string username, int timeout = 10)
{
    int question = QuestionUtils.GenerateQuestion();
    await DiscordUtils.QuestionAsync(_interactive, _context, question, embed, timeout);

    if (await QuestionUtils.QuestionResponse(question))
        Console.WriteLine("yes");
    else
        Console.WriteLine("no");
}

这就是DiscordUtils.QuestionAsync 的样子:

public static async Task QuestionAsync(InteractiveService interactive, SocketCommandContext context, int question, EmbedBuilder embed, int timeout)
{
    await interactive.SendMessageWithReactionCallbacksAsync(
        context, new ReactionCallbackData(null, embed.Build(), false, false, TimeSpan.FromMinutes(timeout))
        .WithCallback(new Emoji("✅"), (_context, _reaction) => QuestionUtils.SetResponse(question, true))
        .WithCallback(new Emoji("❌"), (_context, _reaction) => QuestionUtils.SetResponse(question, false))
    );
}

这就是QuestionUtils.QuestionResponse 的样子:

public static bool QuestionResponse(int question)
{
    while (questions[question] == Response.None)
        Thread.Sleep(100);

    return questions[question] == Response.Yes;
}

基本上,我的回调只会在QuestionUtils.QuestionResponse 完成(循环)时被调用。

但是,我希望在 QuestionUtils.QuestionResponse 循环时调用它们,因此通过“绕过”等待的东西。

所以我不希望DiscordUtils.QuestionAsync 等待QuestionUtils.QuestionResponse 执行QuestionUtils.SetResponse 回调。

我该怎么做?

【问题讨论】:

  • 问题发布 10 秒后给出的 -1 有什么原因吗?
  • 不好笑,没笑。
  • 我真的不明白你为什么要在 while 循环中检查这个。
  • 你的问题对我来说没有任何意义

标签: c# async-await


【解决方案1】:

在使用async/await 时不要使用Thread.Sleep,因为它会阻塞调用线程。而是使用Task.Delay:

public static async Task<bool> QuestionResponse(int question)
{
    while (questions[question] == Response.None)
        await Task.Delay(100);

    return questions[question] == Response.Yes;
}

【讨论】:

  • 不幸的是,这似乎并没有改变任何东西。
  • @Laiteux - 你需要在你的问题中更清楚地解释实际问题是什么。
  • 我不希望DiscordUtils.QuestionAsync 等待QuestionUtils.QuestionResponse 执行QuestionUtils.SetResponse 回调。
【解决方案2】:

使用TaskCompletionSource 手动控制您的Task 何时完成。例如查看官方文档。通过正确的实施,你最终会得到类似await QuestionResponse(1) 或任何你的问题 ID 的东西。如果您想并行运行多个Tasks 并在所有操作完成后继续,请使用Task.WhenAll

【讨论】:

  • 感谢您的回答。但是,我似乎无法理解如何正确实施,以前从未使用过它。你能帮忙吗?
  • 我几乎不明白你在努力实现什么,所以我无法重写你的代码。无论哪种情况,while 部分对我来说似乎都很奇怪。您可以在TaskCompletionSource 的帮助下避免此类事情。如果这不是您所需要的,请以更清晰的方式重写您的问题。
猜你喜欢
  • 2014-11-23
  • 1970-01-01
  • 2021-12-20
  • 1970-01-01
  • 1970-01-01
  • 2021-10-11
  • 1970-01-01
  • 2018-12-09
  • 1970-01-01
相关资源
最近更新 更多