如何修复 "A Reaction handler is blocking the Gateway task"

How to Fix "A Reaction handler is blocking the Gateway task"

所以我遇到的问题是,当许多反应被添加到不和谐的消息中时,我收到以下错误:
A ReactionAdded handler is blocking the gateway task.

只要只添加几个反应,一切似乎都很好,但是当同时(或快速连续)添加多个反应时,我会收到错误消息。

一般来说,ReactionHandler 似乎也需要时间来意识到添加了一个反应。这不应该是因为我在处理程序中做的事情很慢(因为我在那里做的不多)

必要的代码(还有更多,但对于这个问题我认为是不必要的):

class Program
{
   //some variables
   public static Task Main() => new Program().MainAsync();

   public async Task MainAsync()
   {
      using IHost host = Host.CreateDefaultBuilder()
         //some other code
         .AddSingleton<ReactionHandler>())
         .Build();

      await.RunAsync(host);
   }

   public async Task RunAsync(IHost host)
   {
      using IServiceScope serviceScope = host.Services.CreateScope();
      IServiceProvider provider = serviceScope.ServiceProvider;
      //some other code

      var reactions = provider.GetRequiredService<ReactionHandler>();
      reactions.InitializeAsync();
      //some other code

      await _client.LoginAsync(TokenType.Bot, "Token");
      await _client.StartAsync();

      await Task.Delay(-1);
   }
}
public class ReactionHandler
{
   private readonly DiscordSocketClient _client;

   public ReactionHandler(DiscordSocketClient client)
   {
      _client = client;
   }

   public async Task InitializeAsync()
   {
      _client.ReactionAdded += HandleReationAsync;
      _client.ReactionRemoved += HandleReactionAsync;
   }

   private async Task HandleReactionAsync(Cacheable<IUserMessage, ulong> message, Cacheable<IMessageChannel, ulong> channel, SocketReaction reaction)
   {
      if (reaction.User.Value.IsBot) return;

      Console.WriteLine("Reaction changed");
      //some other code
   }
}

因此,如果缺少某些信息(因为我遗漏了一些代码)请告诉我,然后我会添加它。现在,我已经阅读了 MessageReceived Handler 发生的类似事情,但他们的代码与我的代码大不相同,以至于我无法理解。我也读过当我做的代码/事情很慢时会发生这种情况,但上面的代码并没有那么慢,对吧。

我希望一切都清楚并提前致谢:)

如果我对问题的理解正确,那么您似乎正在耗尽应用程序中的所有线程来处理反应。最好使 ReactionHandler 成为托管服务,然后将对该服务的反应排队,这样您就不会等待这些线程。这基本上会使 ReactionHandler 运行 在后台进行处理。

Background tasks with hosted services in ASP.NET Core

请记住,这将在一个完全独立的线程上进行,因此您需要进行调整以使其成为多线程应用程序。

您可以将您的处理程序转换为托管服务,使用一些消息队列解决方案或自己滚动来向服务发出请求。然后客户端(在托管服务之外)将添加到队列中以等待收到反应。