Consuming Events
KSharpPlus makes use of asynchronous events which will execute each handler asynchronously in sequential order. This
event system will require event handlers have a Task
return type and take two parameters.
The first parameter will contain an instance of the KuracordClient which fired the event. The second parameter will contain an arguments object for the specific event you're handling.
Below is a snippet demonstrating this with a lambda expression.
public static async Task Main() {
KuracordClient client = new();
client.MessageCreated += async (s, e) => {
if (e.Message.Content.ToLower().Contains("spiderman"))
await e.Channel.SendMessageAsync("I want pictures of Spiderman!");
};
client.MemberJoined += (s, e) => {
// Non asynchronous code here.
return Task.CompletedTask;
};
}
Alternatively, you can create a new method to consume an event.
public static async Task Main() {
KuracordClient client = new();
client.MessageCreated += MessageCreatedHandler;
client.MemberJoined += MemberJoinedHandler;
}
async Task MessageCreatedHandler(KuracordClient s, MessageCreateEventArgs e) {
if (e.Guild.Id == 564 && e.Author.Id == 42)
await e.Message.DeleteAsync();
}
Task MemberJoinedHandler(KuracordClient s, MemberJoinedEventArgs e) {
// Non asynchronous code here.
return Task.CompletedTask;
}
Avoiding Deadlocks
Despite the fact that your event handlers are executed asynchronously, they are also executed one at a time on the gateway thread for consistency. This means that each handler must complete its execution before others can be dispatched.
Because of this, executing code in your event handlers that runs for an extended period of time may inadvertently create
brief unresponsiveness or, even worse, cause a deadlock.
To prevent such issues, any event handler that has the potential to take more than 2 seconds to execute should have its
logic offloaded to a Task.Run
.
client.MessageCreated += (s, e) => {
_ = Task.Run(async () => {
// Pretend this takes many, many seconds to execute.
SlowWebServiceResponse response = await QuerySlowWebServiceAsync(e.Message.Content);
if (response.StatusCode == HttpStatusCode.OK)
await e.Member.ModifyAsync("Cool nickname");
});
return Task.CompletedTask;
};
Doing this will allow the handler to complete its execution quicker, which will in turn allow other handlers to be executed and prevent the gateway thread from being blocked.