2009-12-22 3 views
0

Проект - C#.События и многопоточный код в .NET

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

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

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

Я бы очень хотел, чтобы пользовательский интерфейс должен был сделать кучу вызова, поскольку его обработчики событий почти всегда будут вызваны из какого-то случайного фонового потока.

ответ

9

Из того, что вы описываете, ваш лучший вариант может заключаться в том, чтобы все ваши объекты принимали SynchronizationContext в качестве аргумента в своем конструкторе.

Если вы это сделаете, когда вам нужно поднять событие, вы можете использовать SyncrhonizationContext.Post для «вызова» события в потоке пользовательского интерфейса.

Таким образом, ваша библиотека будет UI-агностиком (может работать в Windows Forms или WPF), и при необходимости вы можете создавать события в потоке пользовательского интерфейса.

Пользователь вашей библиотеки просто создаст ваш объект, используя SynchronizationContext.Current (который дает вам допустимый контекст в приложениях Windows Forms и WPF, не натягивая ссылку на них).

+0

Да, это так, способ сформировать почтовый вызов немного сложнее, но это будет идеально. –

+0

Я, вероятно, отложил это на отдельный поток, но я увидел пример, где метод, вызывающий событие, сравнивает текущий SyncrhonizationContext с тем, который я храню из пользовательского интерфейса. В WPF они никогда не сравниваются как истинные. Поэтому я получаю бесконечную рекурсию, и пользовательский интерфейс блокируется. Знаете ли вы неплохую проверку агентом, чтобы узнать, нужно ли мне делать сообщение? Должен ли я просто всегда называть это сообщение и просто публиковать мероприятие напрямую? –

+0

Ну, вы всегда можете отправлять/отправлять и не беспокоиться об этом. Он будет иметь (незначительные) накладные расходы, если он не нужен, но обычно это не проблема. Если вы действительно находитесь в фоновом потоке, SynchronizationContext.Current будет пустым (так как «нормальные» потоки не привязаны к контексту). –

0

Использование таймера или ответ на событие, поток пользовательского интерфейса (или объект привязки данных в потоке) может опросить объект «статус» и ограничить объем работы, которую должен выполнить пользовательский интерфейс.

0

Вы изучали модели Facade, Proxy, Factory и Singleton?

Если вы реализуете свой основной объект в качестве Singleton и предоставляете прокси-сервер и методы для создания и доставки этих звонящих в вашу библиотеку, это становится довольно прямым. Шаблон «Фасад» может сделать это проще, отвлекая большинство внутренних элементов того, что происходит в бэкэнде.

Объединение Factory и Singleton и обеспечение того, чтобы все классы, которые вы хотите открыть, имеют конструкторы, требующие вашего основного объекта, - это хороший способ обеспечить выполнение этого проекта. Я не знаю основных требований/дизайна вашей библиотеки, поэтому я не уверен, что это сработает для вас или нет.

+0

Да, это действительно что-то подобное. Я думаю, что в сочетании с SynchronizationContext у меня должно быть все, что нужно, чтобы делать то, что я хочу. –

Смежные вопросы