Форум программистов, компьютерный форум, киберфорум
Visual Basic .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/6: Рейтинг темы: голосов - 6, средняя оценка - 5.00
31 / 31 / 3
Регистрация: 08.08.2011
Сообщений: 195

Обработка RaiseEvent внутри процедуры - насколько возможно?

01.12.2017, 18:51. Показов 1246. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Начал ковыряться в NetMQ.
Основные примеры в C#. С виду - вроде не проблема, однако...
Имеем такой код в C#:
Кликните здесь для просмотра всего текста

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
using System;
using System.Text;
using System.Threading;
using NetMQ;
using NetMQ.Sockets;
 
namespace InterBrokerRouter
{
    public class Client
    {
        private readonly string m_localFrontendAddress;
        private readonly string m_monitorAddress;
        private readonly byte m_id;
 
        /// <summary>
        /// This client will connect its <see cref="RequestSocket"/> to the frontend <see cref="RouterSocket"/> of the broker and
        /// its <see cref="PushSocket"/> to the broker's <see cref="PullSocket"/> as monitor.
        /// It will send a messages and wait at most 10 seconds for an answer before sending an error message via monitor.
        /// If an answer is received it will send a success message via monitor.
        /// </summary>
        /// <param name="localFrontendAddress">The local frontend address of the broker.</param>
        /// <param name="monitorAddress">The monitor address of the broker.</param>
        /// <param name="id">The identity of the client.</param>
        public Client(string localFrontendAddress, string monitorAddress, byte id)
        {
            m_monitorAddress = monitorAddress;
            m_localFrontendAddress = localFrontendAddress;
            m_id = id;
        }
 
        public void Run()
        {
            Console.WriteLine("[CLIENT {0}] Starting", m_id);
 
            var rnd = new Random(m_id);
            // each request shall have an unique id in order to recognize an reply for a request
            var messageId = new byte[5];
            // create clientId for messages
            var clientId = new[] { m_id };
            // a flag to signal that an answer has arrived
            bool messageAnswered = false;
            // we use a poller because we have a socket and a timer to monitor
            using (var clientPoller = new NetMQPoller())
            using (var client = new RequestSocket())
            using (var monitor = new PushSocket())
            {
                client.Connect(m_localFrontendAddress);
                monitor.Connect(m_monitorAddress);
 
                client.Options.Identity = new[] { m_id };
                var timer = new NetMQTimer((int)TimeSpan.FromSeconds(10).TotalMilliseconds);
 
                // use as flag to indicate exit
                var exit = false;
 
                // every 10 s check if message has been received, if not then send error message and ext
                // and restart timer otherwise
                timer.Elapsed += (s, e) =>
                {
                    if (messageAnswered)
                    {
                        e.Timer.Enable = true;
                    }
                    else
                    {
                        var msg = $"[CLIENT {m_id}] ERR - EXIT - lost message {messageId}";
                        // send an error message
                        monitor.SendFrame(msg);
 
                        // if poller is started than stop it
                        if (clientPoller.IsRunning)
                            clientPoller.Stop();
                        // mark the required exit
                        exit = true;
                    }
                };
 
                // process arriving answers
                client.ReceiveReady += (s, e) =>
                {
                    // mark the arrival of an answer
                    messageAnswered = true;
                    // worker is supposed to answer with our request id
                    var reply = e.Socket.ReceiveMultipartMessage();
 
                    if (reply.FrameCount == 0)
                    {
                        // something went wrong
                        monitor.SendFrame($"[CLIENT {m_id}] Received an empty message!");
                        // mark the exit flag to ensure the exit
                        exit = true;
                    }
                    else
                    {
                        var sb = new StringBuilder();
 
                        // create success message
                        foreach (var frame in reply)
                            sb.Append("[" + frame.ConvertToString() + "]");
 
                        // send the success message
                        monitor.SendFrame($"[CLIENT {m_id}] Received answer {sb.ToString()}");
                    }
                };
 
                // add socket & timer to poller
                clientPoller.Add(client);
                clientPoller.Add(timer);
 
                // start poller in another thread to allow the continued processing
                clientPoller.RunAsync();
 
                // if true the message has been answered
                // the 0th message is always answered
                messageAnswered = true;
 
                while (!exit)
                {
                    // simulate sporadic activity by randomly delaying
                    Thread.Sleep((int)TimeSpan.FromSeconds(rnd.Next(5)).TotalMilliseconds);
 
                    // only send next message if the previous one has been replied to
                    if (messageAnswered)
                    {
                        // generate random 5 byte as identity for for the message
                        rnd.NextBytes(messageId);
 
                        messageAnswered = false;
 
                        // create message [client adr][empty][message id] and send it
                        var msg = new NetMQMessage();
 
                        msg.Push(messageId);
                        msg.Push(NetMQFrame.Empty);
                        msg.Push(clientId);
 
                        client.SendMultipartMessage(msg);
                    }
                }
 
                // stop poller if needed
                if (clientPoller.IsRunning)
                    clientPoller.Stop();
            }
        }
    }
}


После переноса в VB получаем:
Кликните здесь для просмотра всего текста

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
Imports System
Imports System.Text
Imports System.Threading
Imports NetMQ
Imports NetMQ.Sockets
 
Namespace InterBrokerRouter
 
    Public Class Client
 
        Private ReadOnly m_localFrontendAddress As String
 
        Private ReadOnly m_monitorAddress As String
 
        Private ReadOnly m_id As Byte
 
        Public Sub New(ByVal localFrontendAddress As String, ByVal monitorAddress As String, ByVal id As Byte)
            m_monitorAddress = monitorAddress
            m_localFrontendAddress = localFrontendAddress
            m_id = id
        End Sub
 
        Public Sub Run()
            Console.WriteLine("[CLIENT {0}] Starting", m_id)
            Dim rnd = New Random(m_id)
            Dim messageId = New Byte(4) {}
            Dim clientId = {m_id}
            Dim messageAnswered As Boolean = False
            Using clientPoller = New NetMQPoller()
                Using client = New RequestSocket()
                    Using monitor = New PushSocket()
                        client.Connect(m_localFrontendAddress)
                        monitor.Connect(m_monitorAddress)
                        client.Options.Identity = {m_id}
                        Dim timer = New NetMQTimer(CInt(TimeSpan.FromSeconds(10).TotalMilliseconds))
                        Dim [exit] = False
                        timer.Elapsed += Function(s, e)
                                             If messageAnswered Then
                                                 e.Timer.Enable = True
                                             Else
                                                 Dim msg = $"[CLIENT {m_id}] ERR - EXIT - lost message {messageId}"
                                                 monitor.SendFrame(msg)
                                                 If clientPoller.IsRunning Then clientPoller.[Stop]()
                                                 [exit] = True
                                             End If
                                         End Function Then
                            client.ReceiveReady += Function(s, e)
                                                   messageAnswered = True
                                                   Dim reply = e.Socket.ReceiveMultipartMessage()
                                                   If reply.FrameCount = 0 Then
                                                       monitor.SendFrame($"[CLIENT {m_id}] Received an empty message!")
                                                       [exit] = True
                                                   Else
                                                       Dim sb = New StringBuilder()
                                                       For Each frame In reply
                                                           sb.Append("[" & frame.ConvertToString() & "]")
                                                       Next
 
                                                       monitor.SendFrame($"[CLIENT {m_id}] Received answer {sb.ToString()}")
                                                   End If
                                               End Function
                        clientPoller.Add(client)
                        clientPoller.Add(timer)
                        clientPoller.RunAsync()
                        messageAnswered = True
                        While Not [exit]
                            Thread.Sleep(CInt(TimeSpan.FromSeconds(rnd.[Next](5)).TotalMilliseconds))
                            If messageAnswered Then
                                rnd.NextBytes(messageId)
                                messageAnswered = False
                                Dim msg = New NetMQMessage()
                                msg.Push(messageId)
                                msg.Push(NetMQFrame.Empty)
                                msg.Push(clientId)
                                client.SendMultipartMessage(msg)
                            End If
                        End While
 
                        If clientPoller.IsRunning Then clientPoller.[Stop]()
                    End Using
                End Using
            End Using
        End Sub
    End Class
End Namespace


Кидаем полученное в VS и получаем на строках timer.Elapsed и client.ReceiveReady сообщение о том, что сие следует использовать с оператором RaiseEvent, что собственно логично и вроде как должно было бы располагаться в отдельных Functions со своим Handler. Вот что стало мне обидно (или интересно), в C# значится можно так воткнуть внутрь процедуры Events на истечение срока таймера а в VB что - никак? Вот не верится! Должно же быть решение, кроме как безусловных переходов из процедуры с хандлером Elapsed... И то, сразу непонятно - как сие организовать, даже если лапотно...
Есть у кого измышления на данную тему?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
01.12.2017, 18:51
Ответы с готовыми решениями:

Возможно ли преобразовать содержимое TextBox в код внутри процедуры/класса?
Добрый вечер. Вопрос следующий: возможно ли перенести текстовое значение из TB в функцию в классе (что бы в этой функции данный текст...

Сделать, чтобы в зависимости от выбранного значения внутри Radiogroup менялась функция внутри процедуры rasposn
Мне нужно чтоб в зависимости от выбранного значения внутри радио группа (rgTypeCis) менялась функция внутри процедуры rasposn. Внутри...

Сократить Path, насколько это возможно
помогите ребята, как можно короче написать путь Bitmap image1 = new Bitmap(&quot;F://Baza//Resurce//load.gif&quot;);

4
 Аватар для ViterAlex
8951 / 4863 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
01.12.2017, 19:12
Оператор += не работает с событиями так как в C#. Вместо него нужно использовать AddHandler
1
31 / 31 / 3
Регистрация: 08.08.2011
Сообщений: 195
01.12.2017, 19:41  [ТС]
Спасибо святой человек! Теперь буду знать!
Осталось довести до ума следующую часть:
Кликните здесь для просмотра всего текста
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
                        AddHandler timer.Elapsed, Function(s, e) As Boolean
                                                      If messageAnswered Then
                                                          e.Timer.Enable = True
                                                      Else
                                                          Dim msg = $"[CLIENT {m_id}] ERR - EXIT - lost message {messageId}"
                                                          monitor.SendFrame(msg)
                                                          If clientPoller.IsRunning Then clientPoller.[Stop]()
                                                          [exit] = True
                                                      End If
                                                  End Function Then
                        AddHandler client.ReceiveReady, Function(s, e) As Boolean
                                                            messageAnswered = True
                                                            Dim reply = e.Socket.ReceiveMultipartMessage()
                                                            If reply.FrameCount = 0 Then
                                                                monitor.SendFrame($"[CLIENT {m_id}] Received an empty message!")
                                                                [exit] = True
                                                            Else
                                                                Dim sb = New StringBuilder()
                                                                For Each frame In reply
                                                                    sb.Append("[" & frame.ConvertToString() & "]")
                                                                Next
                                                                monitor.SendFrame($"[CLIENT {m_id}] Received answer {sb.ToString()}")
                                                            End If
                                                        End Function

В фокусе между двумя событиями (функциями) существует Then которую я недопонимаю как разрешить...
Я опускаю то, что не все ветви кода что-то там возвращают. Недопонимаю, каким образом завершить Then (пробовал разное If в начале функции/функций но в итоге приостановился - недопонимание, хуже регресса)
0
 Аватар для ViterAlex
8951 / 4863 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
01.12.2017, 20:00
Делегаты событий должны быть не функциями, а процедурами. Тогда ничего возвращать не нужно. Про Then не понял...
1
31 / 31 / 3
Регистрация: 08.08.2011
Сообщений: 195
01.12.2017, 20:05  [ТС]
Не бери в голову! Уже понял - при чём тут Function и соответственно Then между ними, если речь идёт о делегатах... А я там давай городить огород... В общем спасибо огромное! (спасибо - от слова спас!)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
01.12.2017, 20:05
Помогаю со студенческими работами здесь

Насколько возможно улучшить комп на материнке ддр2?
насколько возможно улучшить комп на материнке ддр2 ? ведь сейчас все настолько продвинулось. и возможна несовместимость с современными...

Бессмертная программа, которую невозможно (насколько это возможно) убить
Всем доброго времени суток. Необходимо! Создать программу, которую невозможно (насколько это возможно) убить! В чем суть? Надеюсь...

Как узнать насколько возможно увеличить оперативную память asus x54c sx019d
Я смотрел оф сайт Asus, смотрел поиск на форуме, ничего не понял. В ноутбуке - 3 GB RAM, еще давно видел где-то, что можно максимум 4 GB,...

Насколько максимально возможно совместить две системы, и как лучше это сделать?
хочу поставить на одну машину debian и убунту. можно ли совместить что-то кроме директории /home? может быть можно совместиь файлы...

Вызов процедуры внутри процедуры
Здравствуйте, Как правильно это сделать? alter procedure . as BEGIN SELECT DateN FROM Nakl (По факту там одна строка....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru