出于某种原因,我无法捕获订阅事件的匿名异步委托中抛出的异常。
它不会被TestTestAsync
内部捕获(我想因为调用仅等待最快的一次)但是为什么它没有被捕获到未处理或未观察到或崩溃的应用程序中?
ThrowUnobservedTaskExceptions = true也没有任何意义。
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp5
{
class Program
{
static string lockStr = Guid.NewGuid().ToString();
public static void ConsoleWriteLine(string Message, ConsoleColor? color = null)
{
lock (lockStr)
{
var old = Console.ForegroundColor;
if (color != null)
Console.ForegroundColor = color.Value;
Console.WriteLine(Message);
if (color != null)
Console.ForegroundColor = old;
}
}
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
try
{
var cls = new TestClass();
cls.TestAsync += async (s) => await Cls_TestRealAsyncAsync(s);
cls.TestAsync += Cls_TestRealAsync;
Task.Run(async () => await cls.TestTestAsync()).Wait();
Thread.Sleep(5000);
}
catch (Exception ex)
{
ConsoleWriteLine($"{nameof(Main)}: {ex.Message}");
}
}
private static void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
ConsoleWriteLine($"{nameof(TaskScheduler_UnobservedTaskException)}: {(e.Exception as Exception).Message}", ConsoleColor.Yellow);
}
private static Task Cls_TestRealAsync(object sender)
{
try
{
Thread.Sleep(100);
throw new NotImplementedException($"{nameof(Cls_TestRealAsync)}");
}
catch (Exception ex)
{
ConsoleWriteLine(ex.Message, ConsoleColor.Red);
throw;
}
}
private static async Task Cls_TestRealAsyncAsync(object sender)
{
try
{
await Task.Run(() => Thread.Sleep(1000));
throw new NotImplementedException($"{nameof(Cls_TestRealAsyncAsync)}");
}
catch (Exception ex)
{
ConsoleWriteLine(ex.Message, ConsoleColor.Red);
throw;
}
}
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
ConsoleWriteLine($"{nameof(CurrentDomain_UnhandledException)}: {(e.ExceptionObject as Exception).Message}", ConsoleColor.Yellow);
}
}
public class TestClass
{
public delegate Task TestHandlerAsync(object sender);
public event TestHandlerAsync TestAsync;
private async Task OnTestAsync()
{
if (TestAsync != null)
await TestAsync.Invoke(this);
}
public async Task TestTestAsync()
{
try
{
await OnTestAsync();
}
catch (Exception ex)
{
Program.ConsoleWriteLine($"{nameof(TestTestAsync)}: {ex.Message}", ConsoleColor.Green);
}
}
}
}
PS:我在4.7.1上进行了测试
答案 0 :(得分:0)
异步代码不一定是并发代码,但无论如何你应该小心。
此:
app.post('/results', async (req, res) => {
// ...
Promise.all(
lookup('prices', products, countries),
lookup('descriptions', products, countries),
lookup('other', products, countries)
)
.then(values => get_table_data(...values)) // [price_data, description_data, other_data]
.then(table_data => res.render('results.ejs', { table_data }));
});
可能会让您遇到麻烦,因为在调用private async Task OnTestAsync()
{
if (TestAsync != null)
await TestAsync.Invoke(this);
}
时,TestAsync.Invoke
可以为空。
但是你要解决的问题是,不是等待最快的问题,而是等待最后一个问题。
您应修改您的API,但如果您不能,请尝试以下操作:
TestAsync
如果您只关心显示第一个例外。
或者:
public class TestClass
{
public delegate Task TestHandlerAsync(object sender);
public event TestHandlerAsync TestAsync;
private async Task OnTestAsync()
{
var testAsync = this.TestAsync;
if (testAsync == null)
{
return;
}
await Task.WhenAll(
from TestHandlerAsync d in testAsync.GetInvocationList()
select d.Invoke(this));
}
public async Task TestTestAsync()
{
try
{
await OnTestAsync();
}
catch (Exception ex)
{
Program.ConsoleWriteLine($"{nameof(TestTestAsync)}: {ex.Message}", ConsoleColor.Green);
}
}
}
如果你关心所有人。
答案 1 :(得分:0)
找到答案。它没有放弃。由于我的测试控制台的寿命太短,它仍然没有被解雇。
GC.Collect()
将抛出未处理的异常https://blogs.msdn.microsoft.com/ptorr/2014/12/10/async-exceptions-in-c/
在GC期间,它注意到没有人检查过结果(和 因此从未见过例外情况)因此将其作为一个例子 未被观察到的例外。
因此,在main方法结束之前的下一个代码将解决问题并且我看到异常
{{1}}