在第二次使用任何 Async api 调用后,Pi 上的 Bot 崩溃
Posted
技术标签:
【中文标题】在第二次使用任何 Async api 调用后,Pi 上的 Bot 崩溃【英文标题】:Bot on Pi crashes after using any Async api calls a second time 【发布时间】:2018-02-25 22:00:13 【问题描述】:我将我的 Discord 机器人放在了 Rasberry Pi 上,但现在我遇到了问题。当我尝试使用命令时,它第一次起作用。但是第二次使用它时,它只是说“A MessageReceived 处理程序正在阻止网关任务。”而不是工作。不久之后它会说
System.Exception:服务器错过了最后一个心跳 在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] 在:0 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task 任务) [0x0003e] in :0 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task 任务) [0x00028] in :0 在 System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task 任务) [0x00008] in :0 在 System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[TResult].GetResult () [0x00000] in :0 在 Discord.ConnectionManager+c__DisplayClass28_0+
d.MoveNext () [0x0014b] in :0
然后断开连接,尝试重新连接一些但每次都出错。我没有使用命令界面,但我使用的是 async/await。它在我的普通计算机上运行良好,只是在我的 Pi 上中断。
using Discord;
using Discord.WebSocket;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GlurrrBotDiscord
public class Program
DiscordSocketClient client;
static void Main(string[] args) => new Program().MainAsync().GetAwaiter().GetResult();
public async Task MainAsync()
client = new DiscordSocketClient();
try
using(StreamReader sr = new StreamReader("botcode.txt"))
string code = sr.ReadLine();
await client.LoginAsync(TokenType.Bot, code);
catch(Exception e)
Console.WriteLine("Code not found");
Console.WriteLine(e.Message);
await client.StartAsync();
await client.SetGameAsync("praise");
client.MessageReceived += handleMessage;
await Task.Delay(-1);
private async Task handleMessage(SocketMessage msg)
Console.WriteLine(msg.Author + " : " + msg.Content);
if(msg.Content.Contains("/leave"))
var embed = new EmbedBuilder()
Title = msg.Author + " has left",
Description = msg.Author + " has left the Discord and would like everyone to know they did. They are very triggered.",
Color = Color.DarkRed,
;
await msg.Channel.SendMessageAsync("", false, embed);
完整代码在https://github.com/Silthreent/Glurrr-Discord-Bot
【问题讨论】:
在这里发布相关代码。 minimal reproducible example 好吧,任何时候它都使用两个异步调用。if(msg.Content.Contains("/leave")) var embed = new EmbedBuilder() Title = msg.Author + " has left", Description = msg.Author + " has left the Discord and would like everyone to know they did. They are very triggered.", Color = Color.DarkRed, ; await msg.Channel.SendMessageAsync("", false, embed);
可能是最容易展示的地方。 ~~新的堆栈cmets;看起来像垃圾~~
您没有将代码放入 cmets,您需要编辑您的问题并将 Minimal Complete Verifiable 示例放在那里。在更新您的问题之前,请阅读 MickyD 发送给您的链接,您在评论中发布的代码不能作为示例。
好的,我更新了主帖,麻烦您了。
与将答案编辑到问题中相反,您应该将其作为答案发布并接受。
【参考方案1】:
Server missed last heartbeat at
是A MessageReceived handler is blocking the gateway task
的结果,这意味着您正在运行的命令之一使用网关,并使其占用足够长的时间以使连接超时(约 30 秒)。
要解决此问题,您必须实现 a command handler,这是基本机器人实现的一部分。这将允许您异步运行命令,防止线程阻塞。您还可以查看bot sample 以查看上述实现
【讨论】:
无论我等多久,它仍然会在第二个命令上中断。我尝试使用另一个使用命令处理程序的机器人,但它实际上更难破解。它在第一个命令之后中断,执行该命令,然后在不需要第二个命令的情况下给出 MessageRecieved 处理程序问题。 @silthreent 和您是处理程序将其模式设置为异步的用户。并且函数用异步模式属性装饰? 将 runmode 设置为 async 不会给我 MessageRecieved 处理程序消息,但是除了第一个消息之外没有任何消息被发布。 @Silthreent 还确保您将日志级别设置为 LogLevel = LogSeverity.Verbose。或查看我的answer over here 以获取一些登录您的应用程序【参考方案2】:我通过切换到 DiscordSharpPlus 而不是使用 DiscordNet 来修复它,但实际上仍然不知道问题出在哪里。
【讨论】:
以上是关于在第二次使用任何 Async api 调用后,Pi 上的 Bot 崩溃的主要内容,如果未能解决你的问题,请参考以下文章
AFURLConnectionOperation 在第二次下载开始后停止调用 downloadProgressBlock
为啥我的 ViewController 在第二次调用后才发布,iOS ARC?