Обработчики событий запускаются в потоке, который их вызывает, как и любой другой метод.Однако, если обработчик определен в классе, который реализует ISynchronizeInvoke
(например, элементы управления winforms), вы можете вызвать его в потоке, который его создал.Вот метод расширения, который я использую для вызова событий, который автоматически обрабатывает это:
/// <summary>
/// Fires an event and catches any exceptions raised by an event handler.
/// </summary>
/// <param name="ev">The event handler to raise</param>
/// <param name="sender">The sender of the event.</param>
/// <param name="e">Event arguments for the event.</param>
/// <typeparam name="T">The type of the event args.</typeparam>
public static void Fire<T>(this EventHandler<T> ev, object sender, T e) where T : EventArgs
{
if (ev == null)
{
return;
}
foreach (Delegate del in ev.GetInvocationList())
{
try
{
ISynchronizeInvoke invoke = del.Target as ISynchronizeInvoke;
if (invoke != null && invoke.InvokeRequired)
{
invoke.Invoke(del, new[] { sender, e });
}
else
{
del.DynamicInvoke(sender, e);
}
}
catch (TargetInvocationException ex)
{
ex.InnerException.PreserveStackTrace();
throw ex.InnerException;
}
}
}
/// <summary>
/// Called on a <see cref="TargetInvocationException"/> to preserve the stack trace that generated the inner exception.
/// </summary>
/// <param name="e">The exception to preserve the stack trace of.</param>
public static void PreserveStackTrace(this Exception e)
{
var ctx = new StreamingContext(StreamingContextStates.CrossAppDomain);
var mgr = new ObjectManager(null, ctx);
var si = new SerializationInfo(e.GetType(), new FormatterConverter());
e.GetObjectData(si, ctx);
mgr.RegisterObject(e, 1, si);
mgr.DoFixups();
}
РЕДАКТИРОВАТЬ: функция PreserveStackTrace на самом деле не является частью ответа на этот вопрос, это лишь часть решения, которое я использую.Я на самом деле получил этот метод из другого ответа на SO, хотя я не могу точно вспомнить, откуда, но заслуга в этом действительно принадлежит кому-то еще.Извините, я не могу вспомнить, кто.