Поднятие событий в C # из классов - PullRequest
0 голосов
/ 12 апреля 2011

В основном я пытаюсь написать общую реализацию межпроцессного взаимодействия между C # и платформой Android (с использованием Java).

Создание стека сокетов достаточно просто, но меня интересует, что будет хорошим шаблономпередать делегаты в мой класс TcpServer и вызвать необходимые события.

Идея до сих пор такова.

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

        }
}

Поэтому правильная реализация просто представит массив делегатов и использует отражениесопоставить имена событий или что-то в этом роде?Какие у меня варианты?Кроме того, как мне убедиться, что все вызванные события возникают в потоке пользовательского интерфейса, если это все происходит из потока, созданного для сервера?

1 Ответ

1 голос
/ 12 апреля 2011

Если вам не нужно передавать какие-либо пользовательские аргументы обработчику событий, вы можете использовать делегат EventHandler по умолчанию, который использует базовые EventArgs.

Объявите события, которые вы хотите сделать доступными, следующим образом:

public event EventHandler EventReceived;
public event EventHandler ObjectReceived;

Объявите защищенный метод для каждого события, чтобы обработать его для вас. Это действительно просто удобство, чтобы не повторять это каждый раз, когда вам это нужно. Вы можете сделать это встроенным.

Ваши события будут нулевыми, если нет прикрепленных обработчиков событий. Метод обрабатывает проверку перед запуском события.

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

Затем вызовите метод, когда вы хотите вызвать событие. Метод будет обрабатывать проверку, чтобы узнать, слушает ли кто-либо событие.

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

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

Вы можете объявить свой собственный класс для передачи пользовательских аргументов обработчикам событий, используя производные от EventArgs, такие как следующие. По соглашению ваш класс должен называться * что-то * EventArgs.

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

Тогда вам нужно будет объявить пользовательский делегат, который принимает ваш новый параметр args события:

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

Обновите объявления событий, чтобы использовать новый тип делегата вместо EventHandler:

public event EventReceivedEventHandler EventReceived;

И, наконец, при вызове события вы, конечно, захотите создать новый экземпляр вашего класса аргументов пользовательского события и инициализировать ваши пользовательские свойства.

Клиенты могут присоединять к вашим событиям несколько обработчиков, используя обычный синтаксис, и они всегда будут вызываться в правильном потоке.

...