【问题标题】:Action Delegation in C#C# 中的动作委托
【发布时间】:2018-07-24 02:39:22
【问题描述】:

我正在查看 API 示例应用程序中的一些代码,并且需要一些帮助以更好地理解整个示例应用程序中的 Action<T> 委托。我在整个代码中提出了几个问题。任何帮助表示赞赏

API 在Client.cs 类中实现,当我从应用程序发出请求时,API 会将响应发送到Client.cs 中已实现的函数。

/*****  Client.cs  *****/

public event Action<int, int, int> TickSize;

void tickSize(int tickerId, int field, int size)
{
    var tmp = TickSize;

    //What is the point of tmp, and why do we check if it is not null?

    if (tmp != null)
        //This invokes the Action? ie - fires the TickSize Action event?
        tmp(tickerId, field, size);
}

然后UI.cs 类处理 UI 交互并将信息反馈到 UI,以便用户可以看到返回的数据

/*****  UI.cs  *****/

//Delegate to handle reading messages
delegate void MessageHandlerDelegate(Message message);

protected Client client;

public appDialog(){
    InitializeComponent();
    client = new Client();
    .
    .
    //Subscribes the client_TickSize method to the client.TickSize action?
    client.TickSize += client_TickSize;
}

void client_TickSize(int tickerId, int field, int size){
    HandleMessage(new Message(ticketID, field, size));
}

public void HandleMessage(Message message){
    //So, this.InvokeRequired checks if there is another thread accessing the method?
    //Unclear as to what this does and its purpose
    //What is the purpose of the MessageHandlerDelegate callback
    // - some clarification on what is going on here would be helpful
    if (this.InvokeRequired)
        {
            MessageHandlerDelegate callback = new MessageHandlerDelegate(HandleMessage);
            this.Invoke(callback, new object[] { message });
        }
        else
        {
            UpdateUI(message);
        }

}

private void UpdateUI(Message message) { handle messages }

【问题讨论】:

    标签: c# delegates action


    【解决方案1】:

    来自the docs

    事件是一种特殊的多播委托,只能从声明它们的类或结构(发布者类)中调用。如果其他类或结构订阅了该事件,它们的事件处理方法将在发布者类引发事件时被调用

    所以在Client.cs 中有一个名为TickSize 的多播委托。此委托使其他类能够订阅与其关联的事件。因此,在您的函数void tickSize(int tickerId, int field, int size) 中,您希望让所有其他订阅者知道发生了一个滴答事件。

    为此,您首先要查看是否有订阅者。这就是null 检查在if (tmp != null) 中发生的地方。不需要tmp,您可以使用if(TickSize != null) 如果您注册了任何事件处理程序,它将触发并且订阅者将收到该调用。在您的情况下,您确实有订阅者,因为您正在使用以下代码订阅 public AppDialog 中的事件:client.TickSize += client_TickSize;

    所以每当在Client.cs 中调用void tickSize(...) 时,void client_TickSize(...) 中的代码就会运行。这将调用HandleMessage,它将检查是否需要由Invoke 函数调用,因为调用代码不在UI 线程上。如果确实需要使用Invoke 调用它,那么它将使用当前控件的Invoke 函数调用相同的消息(不确定哪个控件,可能是Form)。 HandleMessage 将看到 Invoke 不是必需的,因为调用者在 UI 线程上,然后它将调用 UpdateUi,这将更新控件。

    【讨论】:

    • 谢谢!这非常有帮助 - 只是关于 Invoke 的另一件事,我仍然不明白 MessageHandlerDelegate 在做什么,你能详细说明一下吗?
    • @Adjit MessageHandlerDelegateInvoke 的回调函数。 Invoke 将一个委托作为参数,它将在 UI 线程上调用,因此在您的情况下,您将传递 MessageHandlerDelegate Invoke 引用 HandleMessage(Message message)
    • 谢谢!我希望我能给你一个额外的 +1,非常感谢你的帮助。
    猜你喜欢
    • 1970-01-01
    • 2010-09-27
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 2012-07-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多