在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
,每次创建一个新的命令实例。