События и многопоточный код в.NET
Проект на C#.
Итак, у меня есть куча многопоточного кода, который предназначен для работы в качестве библиотеки. Это отдельный проект от пользовательского интерфейса.
В моей библиотеке есть центральный объект, который нужно создать, прежде чем что-либо, что вызовет события.
Может ли этот главный объект передаваться в некоторых объектах, чтобы мои события могли выяснить, когда их нужно будет вызвать, чтобы вернуться в основной поток пользовательского интерфейса?
Мне бы очень хотелось, чтобы пользовательский интерфейс не вызывал кучу вызовов, поскольку его обработчики событий почти всегда будут вызываться из некоторого случайного фонового потока.
3 ответа
Исходя из того, что вы описываете, лучше всего сделать так, чтобы все ваши объекты принимали SynchronizationContext в качестве аргумента в своем конструкторе.
Если вы делаете это, когда вам нужно вызвать событие, вы можете использовать SyncrhonizationContext.Post, чтобы "вызвать" событие в потоке пользовательского интерфейса.
Таким образом, ваша библиотека будет независима от пользовательского интерфейса (может работать в Windows Forms или WPF), и вы сможете вызывать события в потоке пользовательского интерфейса по мере необходимости.
Пользователь вашей библиотеки просто создаст ваш объект, используя SynchronizationContext.Current (который дает вам действительный контекст в приложениях Windows Forms и WPF, без добавления ссылки ни на один из них).
Используя таймер или отвечая на событие, поток пользовательского интерфейса (или объект с привязкой к данным в потоке) может опрашивать объект "статус" и ограничивать объем работы, который должен выполнять пользовательский интерфейс.
Вы смотрели на шаблоны Фасад, Прокси, Фабрика и Синглтон?
Если вы реализуете свой базовый объект как Singleton, и предоставляете прокси и фабричные методы для производства и доставки их вызывающим сторонам вашей библиотеки, это становится довольно простым. Шаблон Facade может сделать это проще, абстрагируя большинство внутренних элементов от того, что происходит в бэкэнде.
Объединение Factory и Singleton и обеспечение того, чтобы все классы, которые вы хотите предоставить, имели конструкторы, требующие вашего основного объекта, - хороший способ реализовать этот дизайн. Я не знаю основных требований / дизайна вашей библиотеки, поэтому я не уверен, будет ли это работать для вас или нет.