Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
Си-решеточник
 Аватар для Rameron
141 / 135 / 60
Регистрация: 07.02.2011
Сообщений: 669
.NET 2.x

Как реализовать генерацию события в основном потоке?

24.03.2017, 12:39. Показов 1015. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем здравствуйте!

У меня есть некий класс, в котором в отдельном потоке выполняется циклическая операция, после каждой с итераций которой генерируется событие. В аргументе этого события содержится строка, которая должна выводится в текстовом поле формы. И вот проблема: событие генерируется в в том отдельном потоке и, соответственно, назначенный обработчик события тоже выполняется в том же потоке. В нём изменить значение текстового поля, конечно, можно, но я не люблю использовать "Invoke". По этому хотелось бы узнать, как сразу сгенерировать событие в UI-потоке.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
24.03.2017, 12:39
Ответы с готовыми решениями:

GDI+. Почему в отдельном потоке картинки сохраняются как белые прямоугольники, а в основном потоке - всё Ок?
Всем привет, делаю функцию уменьшения картинок при помощи библиотеки GDI+, в отдельном потоке происходит уменьшение картинки и её...

Почему если делегат события определен в другом классе, то не получается создать генерацию события?
В проекте №1 объявлен делегат для события: delegate void StateEventHandler(State state); А в своем проекте №2 я в классе создаю событие...

Как вызвать асинхронную функцию в основном потоке и дождаться результата ?
Ситуация такая : запускаю фоновый поток из основного (интерфейсного) для проверки обновления Task.Run(()=>CheckUpdate()); В...

9
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
24.03.2017, 13:01
Цитата Сообщение от Rameron Посмотреть сообщение
я не люблю использовать "Invoke"
А вашу любовь/не любовь правила ЯП не интересуют. Invoke - это один из стандартных способов маршалинга в поток UI, и ничего с этим не поделать. Можете еще использовать контекст синхронизации, хотя вряд ли от этого будет меньше кода.
Еще выход - писать и использовать свои компоненты UI, безопасные к обращению из других потоков, но сами понимаете, внутри будет использоваться тот же механизм (Invoke/SynchronizationContext).
0
24.03.2017, 13:01

Не по теме:

Цитата Сообщение от Rameron Посмотреть сообщение
но я не люблю использовать "Invoke"
это пять...

0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18287 / 14210 / 5368
Регистрация: 17.03.2014
Сообщений: 28,889
Записей в блоге: 1
24.03.2017, 14:31
Rameron, можно использовать класс AsyncOperationManager по аналогии с классом BackgroundWorker.
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
class Test
{
    public event EventHandler MyEvent;
    
    AsyncOperation _asyncOp;
    SendOrPostCallback _callback;
    
    public Test()
    {
        _asyncOp = AsyncOperationManager.CreateOperation(null);
        _callback = new SendOrPostCallback(RaiseMyEvent);
    }
    
    public void Run()
    {
        new Thread(DoSmth).Start();
    }
    
    void DoSmth()
    {
        for (int i=0; i<5; i++)
        {
            Thread.Sleep(500);
            _asyncOp.Post(_callback, EventArgs.Empty);
        }
    }
    
    void RaiseMyEvent(object arg)
    {
        if (MyEvent != null) MyEvent(this, (EventArgs)arg);
    }
}
Использование
C#
1
2
3
4
5
Test t = new Test();
t.MyEvent += OnMyEvent;
// Запускаем свою операцию. Обработчики события MyEvent будут срабатывать в потоке который выдает SynchronizationContext
// Для GUI приложений это будет UI поток
t.Run();
2
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10427 / 5157 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
24.03.2017, 18:19
OwenGlendower, Зачем все так сложно? AsyncOperation, колбек...
Просто пишем один раз вот такое расширение:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    public static class EventExtensions
    {
        public static object Raise<T>(this MulticastDelegate multicastDelegate, object sender, T e) where T : EventArgs
        {
            object retVal = null;
            var threadSafeMulticastDelegate = multicastDelegate;
 
            if (threadSafeMulticastDelegate != null)
            foreach (Delegate d in threadSafeMulticastDelegate.GetInvocationList())
            {
                var synchronizeInvoke = d.Target as ISynchronizeInvoke;
                if ((synchronizeInvoke != null) && synchronizeInvoke.InvokeRequired)
                    retVal = synchronizeInvoke.EndInvoke(synchronizeInvoke.BeginInvoke(d, new[] { sender, e }));
                else
                    retVal = d.DynamicInvoke(new[] { sender, e });
            }
 
            return retVal;
        }
    }
После чего просто вызываем метод Raise у любого нашего события. Событие будет обработано в контексте UI потока подписчика.
2
1167 / 885 / 517
Регистрация: 09.04.2014
Сообщений: 2,099
24.03.2017, 18:31
Красиво, но в .NET 2.x работать не будет...
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10427 / 5157 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
24.03.2017, 18:34
Цитата Сообщение от nedel Посмотреть сообщение
Красиво, но в .NET 2.x работать не будет...
Ну в 2.0 просто нужно вызывать явно:
C#
1
EventExtensions.Raise(myEvent, ...);
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18287 / 14210 / 5368
Регистрация: 17.03.2014
Сообщений: 28,889
Записей в блоге: 1
24.03.2017, 18:45
Цитата Сообщение от Storm23 Посмотреть сообщение
Зачем все так сложно? AsyncOperation, колбек...
Для большего универсализма. WPF элементы управления не реализуют ISynchronizeInvoke. В отсутствие этого интерфейса вызовы пойдут в пуле потоков. Это же произойдет если обработчик события объявлен как static. (Хотя если он static то он возможно и не обращается к элементам управления). Решение тем не менее интересно. Спасибо что выложил.
0
Си-решеточник
 Аватар для Rameron
141 / 135 / 60
Регистрация: 07.02.2011
Сообщений: 669
24.03.2017, 19:14  [ТС]
Спасибо за интересные решения, буду смотреть, что мне лучше подходит
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10427 / 5157 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
24.03.2017, 20:15
Цитата Сообщение от OwenGlendower Посмотреть сообщение
WPF элементы управления не реализуют ISynchronizeInvoke.
Для WPF делается почти также, только вместо ISynchronizeInvoke нужно приводить к DispatcherObject.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
24.03.2017, 20:15
Помогаю со студенческими работами здесь

Как записать строку созданную в основном потоке в texbox работающем в backgroundworker?
Здравствуйте, попытаюсь вкратце описать суть проблемы. У меня есть 8-ми канальный измеритель температуры, каждую секунду я хочу опрашивать...

Как реализовать генерацию букв в игре
Делаю игру и пришел в тупик, задача состоит в том что на экране есть 7 облаков и в самом верхнем будет появляться рандомная буква на...

Как реализовать автоматическую генерацию номеров документов
Есть таблица Number с полем Num, в которое будут записываться автоматически генерируемые номера документов. Как это реализовать? Я решил...

Как реализовать генерацию чисел от 000000 до 999999
Здравствуйте, подскажите пожалуйста, как реализовать генерацию от 000000 до 999999, VB заменяет мне 6 нулей на один и отсчет идет от 0, то...

Как можно программно реализовать генерацию случайных графов
1) Какие бывают еще случайные графы, кроме графа Эрдеша-Реньи? 2) Как можно программно реализовать генерацию случайных графов?


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru