C#中的动作委派

时间:2018-07-24 02:39:22

标签: c# delegates action

我正在查看来自示例应用程序的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 }

1 个答案:

答案 0 :(得分: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;

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