简体   繁体   English

从类中引发C#事件

[英]Raising events in C# from classes

Basically I am attempting to write a generic interprocess communication implementation between C# and the Android platform (using Java). 基本上,我试图在C#和Android平台(使用Java)之间编写通用的进程间通信实现。

Creating the socket stack is simple enough but what I am wondering is what would be a good pattern to passing in delegates into my TcpServer class and raising the required events. 创建套接字堆栈非常简单,但是我想知道的是将委托传递到我的TcpServer类中并引发所需事件的好模式。

The idea so far is. 到目前为止的想法是。

while (connected) {
    //Compile all the required data and so forth
        switch (currentState)
        {
               case CurrentServerState.EventReceived:
                    //Raise my event...
               break;
               case CurrentServerState.ObjectReceived:
               break;

        }
}

So would the correct implementation simply expose an array of delegates and use reflection to match event names or something along those lines? 那么正确的实现是否会简单地公开一组委托并使用反射来匹配事件名称或类似的名称? What are my options? 我有什么选择? Also how do I make sure that any raised events are raised in the UI thread given that this is all occurring from a thread created for the server? 另外,考虑到这都是从为服务器创建的线程中发生的,我如何确保UI线程中引发了任何引发的事件?

If you don't need to pass any custom arguments to the event handler you can use the default EventHandler delegate which uses the base EventArgs. 如果不需要将任何自定义参数传递给事件处理程序,则可以使用使用基本EventArgs的默认EventHandler委托。

Declare the events you want to make available like this: 声明您要提供的事件,如下所示:

public event EventHandler EventReceived;
public event EventHandler ObjectReceived;

Declare a protected method for each event to handle raising the event for you. 为每个事件声明一个受保护的方法来为您处理引发事件。 This is really just a convenience to keep from repeating this each time you need it. 实际上,这只是避免每次需要重复此操作时的一种方便。 You could do this inline. 您可以内联进行。

Your events will be null if there are no attached event handlers. 如果没有附加的事件处理程序,您的事件将为null。 The method handles checking for this before firing the event. 该方法在触发事件之前进行检查。

protected void RaiseEventReceived(EventArgs e)
{
    if (EventReceived != null)
        EventReceived(this, e);
}

Then call the method when you want to raise the event. 然后在要引发事件时调用该方法。 The method will handle checking to see if anyone is listening for the event. 该方法将进行检查以查看是否有人在监听该事件。

public void SomeOtherMethod()
{
    while (IsConnected)
    {
        switch (CurrentState)
        {
            case CurrentServerState.EventReceived:
                RaiseEventReceived(EventArgs.Empty);
                break;

            case CurrentServerState.ObjectReceived:
                RaiseObjectReceived(EventArgs.Empty);
                break;
        }
    }
}

You can declare your own class to pass custom arguments to the event handlers by deriving from EventArgs such as the following. 您可以声明自己的类,以通过从EventArgs派生以下类将自定义参数传递给事件处理程序。 By convention your class should be named *something*EventArgs. 按照约定,您的类应命名为* something * EventArgs。

public class EventReceivedEventArgs : EventArgs
{
    // Declare properties to hold additional event info here
}

Then you would need to declare a custom delegate that takes your new event args parameter: 然后,您需要声明一个采用新事件args参数的自定义委托:

public delegate void EventReceivedEventHandler(object sender, EventReceivedEventArgs e);

Update your event declarations to use your new delegate type instead of EventHandler: 更新事件声明以使用新的委托类型而不是EventHandler:

public event EventReceivedEventHandler EventReceived;

And finally, when raising the event you of course would want to create a new instance of your custom event arguments class and intitialize your custom properties. 最后,当引发事件时,您当然希望创建自定义事件参数类的新实例并初始化您的自定义属性。

Clients can attach multiple handlers to your events using the normal syntax and they will always be called on the correct thread. 客户端可以使用常规语法将多个处理程序附加到您的事件,并且它们将始终在正确的线程上被调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM