在c#字典中引用异步任务
现在,我在几个程序中遇到了字典中异步任务的问题,我不知道如何解决它 我有一个异步任务,如下所示:在c#字典中引用异步任务,c#,async-await,task,C#,Async Await,Task,现在,我在几个程序中遇到了字典中异步任务的问题,我不知道如何解决它 我有一个异步任务,如下所示: MessageEventArgs.Channel.SendMessage("somestring"); public static Dictionary<string, Task> myDict= new Dictionary<string, Task>() { {"!example", MessageEventArgs.Channel.SendMessage("H
MessageEventArgs.Channel.SendMessage("somestring");
public static Dictionary<string, Task> myDict= new Dictionary<string, Task>()
{
{"!example", MessageEventArgs.Channel.SendMessage("HelloWorld") }
}
MessageEventArgs
是我在程序开始时静态声明的第三方库中的一个类:
public static MessageEventArgs meargs;
程序侦听IRC通道中的事件,并根据文本命令执行操作。我不希望每个命令都有一个巨大的switch语句,而是希望制作一个字典,将字符串与方法相匹配。并不是所有人都只是发送消息,所以我不能只存储要发送的字符串。看起来是这样的:
MessageEventArgs.Channel.SendMessage("somestring");
public static Dictionary<string, Task> myDict= new Dictionary<string, Task>()
{
{"!example", MessageEventArgs.Channel.SendMessage("HelloWorld") }
}
我意识到,当字典被实例化时,它会尝试调用SendMessage,因为它是一个异步任务。MessageEventArgs在之后才会实例化,因此它会引发异常。有没有办法在字典中存储对这些函数的引用?我找到了使用代理的解决方案,但它们似乎不适用于void
方法,而async
方法(据我所知)只能返回void
或Task
提前谢谢 如果我写这篇文章,我会创建一个带有虚拟
ExecuteCommand
函数的ircommand
类。然后为我希望能够运行的每个不同命令创建一个子类。每个子类都将使用调用命令所需的逻辑覆盖ExecuteCommand
函数ExecuteCommand
可以采用与调用命令的通道对应的Channel
类型的参数
在启动时,我将创建一个字典
,其中填充了命令文本的键
,以及实现该命令的子类的新实例的值
当一个命令进入时,我会使用匹配的键从字典中拉出ircommand
实例,并在其上调用ExecuteCommand
函数,传入从中接收命令的通道
可能会发生这样的事情。我实际上没有打开VisualStudio来验证我的语法,所以这里可能有一些错误
一些命令的实现:
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]();
publicstaticdictionary myDict=newdictionary()
{
{“!example”,()=>MessageEventArgs.Channel.SendMessage(“HelloWorld”)}
}
等待myDict[e.Message.Text]();
在初始化myDict时,您是否尝试过“新建”SendMessage实例?是否确实应该将MessageEventArgs作为静态变量保留下来?它的名字让我觉得它是EventArgs
的一个子类,每次事件发生时都会发送给您。我从来没有真正遇到过这样的情况,把它们作为长寿实例保存是一个好主意。@JustinR。我没有尝试过,但我会尝试一下。@BradleyUffner实际上你是对的。完全错过了。我将摆脱它,并找到另一种调用SendMessage的方法,即任务“操作”的签名-即任务实际执行的方法-对所有任务都是相同的?如果是的话,请分享。我添加了更多的示例代码,包括一个不仅仅是发送文本的命令,这会让你更好地理解我所说的。这太完美了。设置它需要更多的工作,但是我的Program.cs现在更干净了,这将使将来添加新命令变得更容易。非常感谢。在这个实现中要小心,不要在单个irc命令中存储任何类型的状态。因为每个命令只有一个实例,所以它们都将共享该状态。如果需要存储状态,可以修改该模式,以便该命令字典存储要执行的ircommand
的类型,然后使用反射,特别是Activator.CreateInstance
,每次创建一个新的命令实例。