摘自Stephen Cleary关于异步等待的文章:
图2异步无效方法的异常无法通过Catch捕获
private async void ThrowExceptionAsync()
{
throw new InvalidOperationException();
}
public void AsyncVoidExceptions_CannotBeCaughtByCatch()
{
try
{
ThrowExceptionAsync();
}
catch (Exception)
{
// The exception is never caught here!
throw;
}
}
Run Code Online (Sandbox Code Playgroud)
...异步void方法抛出的任何异常将直接在异步void方法启动时处于活动状态的SynchronizationContext上引发...
这究竟意味着什么?我写了一个扩展示例来尝试收集更多信息.它具有与图2相同的行为:
static void Main()
{
AppDomain.CurrentDomain.UnhandledException += (sender, ex) =>
{
LogCurrentSynchronizationContext("AppDomain.CurrentDomain.UnhandledException");
LogException("AppDomain.CurrentDomain.UnhandledException", ex.ExceptionObject as Exception);
};
try
{
try
{
void ThrowExceptionVoid() => throw new Exception("ThrowExceptionVoid");
ThrowExceptionVoid();
}
catch (Exception ex)
{
LogException("AsyncMain - Catch - ThrowExceptionVoid", ex);
}
try
{
// CS1998 …Run Code Online (Sandbox Code Playgroud) .Returns<T> (this T value, ... )扩展方法如何在引擎盖下工作?
具体来说,如何.Returns根据执行该方法的结果知道它打算配置什么方法?
例:
public interface ICalculator { Add(int a, int b); }
// create mock
var calculator = Substitute.For<ICalculator>();
// How does this piece work under the hood?
calculator.Add(1, 2).Returns(3);
Run Code Online (Sandbox Code Playgroud)