與異步委託
一般來說,如果該委託方法拋出異常的線程終止,異常將再次調用代碼只有,當你調用EndInvoke
被拋出。
這就是爲什麼當使用異步委託(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);
}
-1:你的回答也表明,調用'ThreadPool.QueueUserWorkItem'和一個引發異常的方法將導致該框架被異常所吞噬,這在版本2.0和之後並不是這樣。 –
@JoãoAngelo:ThreadPool一般不會拋出異常,例如新的C#4.0任務不會拋出異常,而是像tnd.Wait方法一樣拋出EndInvoke方法。 –
你完全正確。我只是很愚蠢! –