Обычно с асинхронными делегатами, если делегированный метод генерирует исключение, поток прерывается, и исключение будет снова выдано в вызывающем коде только при вызове EndInvoke
.
ThisВот почему при использовании асинхронного делегата (BeginInvoke
) вы всегда должны вызывать EndInvoke
.Кроме того, это не следует путать с Control.BeginInvoke
, который может быть вызван методом пожара и забвения.
Ранее я обычно говорил, потому что есть возможность заявить, что исключение следует игнорировать, еслиМетод делегата возвращает void.Для этого необходимо пометить метод атрибутом OneWay
.
Если вы запустите следующий пример, вы получите исключение только при вызове willNotIgnoreThrow.EndInvoke
.
static void Throws()
{
Console.WriteLine("Thread: {0}", Thread.CurrentThread.ManagedThreadId);
throw new ApplicationException("Test 1");
}
[OneWay]
static void ThrowsButIsIgnored()
{
Console.WriteLine("Thread: {0}", Thread.CurrentThread.ManagedThreadId);
throw new ApplicationException("Test 2");
}
static void Main(string[] args)
{
Console.WriteLine("Main: {0}", Thread.CurrentThread.ManagedThreadId);
var willIgnoreThrow = new Action(ThrowsButIsIgnored);
var result1 = willIgnoreThrow.BeginInvoke(null, null);
Console.ReadLine();
willIgnoreThrow.EndInvoke(result1);
Console.WriteLine("============================");
var willNotIgnoreThrow = new Action(Throws);
var result2 = willNotIgnoreThrow.BeginInvoke(null, null);
Console.ReadLine();
willNotIgnoreThrow.EndInvoke(result2);
}