У меня простой вопрос, но я примерно на 80% уверен, что ответ на вопрос будет сопровождаться «вы делаете это неправильно», поэтому я собираюсь задать и непростой вопрос.
Простой вопрос: у меня есть публичный метод публичного класса. Я хочу, чтобы он генерировал исключение, если он вызывается в потоке пользовательского интерфейса. Как я могу это сделать?
Гораздо менее простой вопрос: есть ли более простой способ реорганизовать этот дизайн?
Фон:
Я разработал настольную программу, которая взаимодействует с устаревшим приложением через его API. API не является удаленно поточно-ориентированным. Я построил библиотеку классов, которая инкапсулирует взаимодействие с API (которое включает в себя маршалинг и демаршаллинг данных в огромном буфере byte [], а затем вызывает внешнюю функцию, загруженную из DLL), так что многие детали реализации устаревшего API скрыты из моего кода, насколько это возможно. Поскольку я знал, что создание нескольких экземпляров основного объекта API будет катастрофой, я реализовал его как статический класс.
Я также создал набор классов для запуска заданий в фоновом режиме моего приложения. TaskManager
поддерживает очередь из Task
объектов и запускает их, используя BackgroundWorker
. Использование фонового потока позволяет пользовательскому интерфейсу настольного приложения оставаться отзывчивым во время взаимодействия с устаревшим унаследованным приложением; использование очереди гарантирует, что только одна задача вызывает API в любой момент времени.
К сожалению, я никогда не думал встроить определенные средства защиты в этот дизайн. Недавно я обнаружил места в коде, где я непосредственно вызывал API в потоке пользовательского интерфейса. Я полагаю, что исправил их все, но я хотел бы гарантировать, что я не сделаю это снова.
Если бы я спроектировал это правильно с самого начала, я бы сделал класс обертки API нестатичным, скрыл его конструктор от всего, кроме TaskManager
, а затем передал бы экземпляр класса API каждому Task
когда оно будет создано. Любому методу, вызываемому Task
, который говорил с API, нужно будет передать объект API. Это сделало бы невозможным использование API в основном потоке.
Дело в том, что существует много кода, который взаимодействует с API. Внедрение этого изменения (которое, я думаю, в конечном итоге правильно) затронет все это. Итак, я хотел бы изменить метод API Call
, чтобы он вызывал исключение, если он вызывается в потоке переднего плана.
Я знаю, что решаю не ту проблему. Я чувствую это в своих костях. Но я и сейчас довольно увлечен этим и не могу найти правильного решения.
Edit:
Я четко сформулировал вопрос неправильно, поэтому было трудно ответить. Я не должен спрашивать "Как этот метод может знать, работает ли он в потоке пользовательского интерфейса?" Реальный вопрос: «Как этот метод может узнать, работает ли он в потоке неправильный ?» Может (в теории) работать тысяча потоков. Как указывает JaredPar, может быть несколько потоков пользовательского интерфейса. Только один поток является правильным потоком, и его идентификатор легко найти.
На самом деле, даже после того, как я реорганизовал этот код так, чтобы он был должным образом спроектирован (что я в основном делал сегодня), стоит иметь в API механизм, который проверяет, выполняется ли он в соответствующем потоке.