В моих C++/Qt-приложениях, когда я хочу поднять сигнал/событие, я просто буду делать:
emit Event();
Это вызовет все обработчики для Event()
в том же потоке, что и объекты, подписавшиеся на это событие.
С#, похоже, не предлагает ничего подобного, поэтому как мне это сделать?
У меня есть класс, позвольте ему назвать EventRaiser
, у которого есть событие SomethingHappened
и метод, который вызывает событие при необходимости:
class EventRaiser
{
public event EventHandler SomethingHappened;
void RaiseEvent()
{
var anyoneWhosInterested = SomethingHappened;
if (anyoneWhosInterested != null)
{
try { anyoneWhosInterested(this, new EventArgs()); }
catch { /* we don't care */ }
}
}
}
Моя проблема в том, что RaiseEvent()
вызовет обработчики в потоке RaiseEvent()
. Но мне нужно вызвать обработчиков в потоках, подписанных на событие.
Как мне это сделать?
Я на.NET 2.0 и Visual Studio 2012.
В целом эта идея не имеет смысла, потому что вы не можете произвольно прерывать запуск кода в другом потоке и вводить событие. Эта архитектура может привести к большому количеству случайных поломков.
Сделайте подписчиков обработкой синхронизации и маршалинга. Они знают, в какой поток они работают, и как безопасно маршировать вызов на него.
Рассмотрите возможность захвата текущего SynchronizationContext
в обработчике SomethingHappened.add
и отправке/отправке события в этот SynchronizationContext
. Это работает только в том случае, если подписанный поток имеет значимый контекст.