在 C# 字典中引用异步任务
Referencing asynchronous tasks in a c# dictionary
我现在在几个程序中遇到了关于字典中异步任务的问题,我不知道如何解决它。
我有一个看起来像这样的异步任务:
MessageEventArgs.Channel.SendMessage("somestring");
MessageEventArgs
是来自第三方库的 class,我在程序开始时静态声明:
public static MessageEventArgs meargs;
该程序侦听 IRC 频道中的事件并根据文本命令执行操作。我不想为每个命令都有一个巨大的 switch 语句,而是想制作一个将字符串与方法匹配的字典。并不是所有的都只是发送消息,所以我不能只存储要发送的字符串。它看起来像这样:
public static Dictionary<string, Task> myDict= new Dictionary<string, Task>()
{
{"!example", MessageEventArgs.Channel.SendMessage("HelloWorld") }
}
在 Main() 中,我调用:
MessageReceived += async (s,e) =>
{
meargs = e;
await myDict[e.Message.Text];
}
我逐渐意识到,当字典被实例化时,它会尝试调用 SendMessage,因为它是一个异步任务。 MessageEventArgs 直到之后才被实例化,因此它会抛出异常。有没有办法将对这些函数的引用存储在字典中?我找到了使用委托的解决方案,但它们似乎不适用于 void
方法,并且 async
方法(据我所知)只能 return void
或 Task
.
提前致谢!
如果我正在写这篇文章,我会创建一个带有虚拟 ExecuteCommand
函数的 IrcCommand
class。然后为每个我希望能够 运行 的不同命令创建一个 subclass。每个 subclass 将使用调用命令所需的逻辑覆盖 ExecuteCommand
函数。 ExecuteCommand
可以接受类型为 Channel
的参数,对应于调用命令的通道。
在启动时,我会创建一个 Dictionary<string, IrcCommand>
,其中填充了命令文本的 Key
,以及子 class 的新实例的 Value
执行该命令。
当命令进入时,我会使用匹配的键从字典中提取 IrcCommand
实例,并在其上调用 ExecuteCommand
函数,传入 Channel
命令是收到。
可能会发生这样的事情。我实际上并没有打开 visual studio 来验证我的语法,所以这里可能有一些错误。
一些命令的实现:
public class ExampleCommand : IrcCommand
{
public override void ExecuteCommand(Channel channel)
{
channel.SendMessage("Hello World");
}
}
public class DisconnectCommand : IrcCommand
{
public override void ExecuteCommand(Channel channel)
{
channel.Disconnect();
}
}
在应用程序启动时注册命令:
private void RegisterCommands()
{
_commands.add("!example", new ExampleCommand());
_commands.add("!disconnect", new DisconnectCommand());
}
收到命令后执行:
_commands(commandText).ExecuteCommand(e.channel);
不是立即创建任务,而是存储工厂:
public static Dictionary<string, Func<Task>> myDict= new Dictionary<string, Func<Task>>()
{
{"!example", () => MessageEventArgs.Channel.SendMessage("HelloWorld") }
}
await myDict[e.Message.Text]();
我现在在几个程序中遇到了关于字典中异步任务的问题,我不知道如何解决它。
我有一个看起来像这样的异步任务:
MessageEventArgs.Channel.SendMessage("somestring");
MessageEventArgs
是来自第三方库的 class,我在程序开始时静态声明:
public static MessageEventArgs meargs;
该程序侦听 IRC 频道中的事件并根据文本命令执行操作。我不想为每个命令都有一个巨大的 switch 语句,而是想制作一个将字符串与方法匹配的字典。并不是所有的都只是发送消息,所以我不能只存储要发送的字符串。它看起来像这样:
public static Dictionary<string, Task> myDict= new Dictionary<string, Task>()
{
{"!example", MessageEventArgs.Channel.SendMessage("HelloWorld") }
}
在 Main() 中,我调用:
MessageReceived += async (s,e) =>
{
meargs = e;
await myDict[e.Message.Text];
}
我逐渐意识到,当字典被实例化时,它会尝试调用 SendMessage,因为它是一个异步任务。 MessageEventArgs 直到之后才被实例化,因此它会抛出异常。有没有办法将对这些函数的引用存储在字典中?我找到了使用委托的解决方案,但它们似乎不适用于 void
方法,并且 async
方法(据我所知)只能 return void
或 Task
.
提前致谢!
如果我正在写这篇文章,我会创建一个带有虚拟 ExecuteCommand
函数的 IrcCommand
class。然后为每个我希望能够 运行 的不同命令创建一个 subclass。每个 subclass 将使用调用命令所需的逻辑覆盖 ExecuteCommand
函数。 ExecuteCommand
可以接受类型为 Channel
的参数,对应于调用命令的通道。
在启动时,我会创建一个 Dictionary<string, IrcCommand>
,其中填充了命令文本的 Key
,以及子 class 的新实例的 Value
执行该命令。
当命令进入时,我会使用匹配的键从字典中提取 IrcCommand
实例,并在其上调用 ExecuteCommand
函数,传入 Channel
命令是收到。
可能会发生这样的事情。我实际上并没有打开 visual studio 来验证我的语法,所以这里可能有一些错误。
一些命令的实现:
public class ExampleCommand : IrcCommand
{
public override void ExecuteCommand(Channel channel)
{
channel.SendMessage("Hello World");
}
}
public class DisconnectCommand : IrcCommand
{
public override void ExecuteCommand(Channel channel)
{
channel.Disconnect();
}
}
在应用程序启动时注册命令:
private void RegisterCommands()
{
_commands.add("!example", new ExampleCommand());
_commands.add("!disconnect", new DisconnectCommand());
}
收到命令后执行:
_commands(commandText).ExecuteCommand(e.channel);
不是立即创建任务,而是存储工厂:
public static Dictionary<string, Func<Task>> myDict= new Dictionary<string, Func<Task>>()
{
{"!example", () => MessageEventArgs.Channel.SendMessage("HelloWorld") }
}
await myDict[e.Message.Text]();