gpt4 book ai didi

c# - 我可以捕获 C# 中泛型参数传入的类型的异常吗?

转载 作者:太空宇宙 更新时间:2023-11-03 18:53:09 25 4
gpt4 key购买 nike

以这段代码为例 - 我认为当显示 TException 时,我应该能够“捕获”它并重试我的 func() 适当次数。但是当我将这段代码放在野外时,即使抛出了 TException 类型的异常,它也会跳过 catch 子句并冒泡。谁能解释一下为什么?

public static T TryNTimes<T, TException>(Func<T> func, int times) where TException : Exception
{
if (times <= 0)
throw new ArgumentException($"TryNTimes: `times` must be a positive integer. You passed in: {times}");

while (times > 0)
{
try
{
return func();
}
catch (TException)
{
if (--times <= 0)
throw;
}
}

// should never reach here
return default(T);
}

代码是这样调用的:

await RetryUtils.TryNTimes<Task, MyCustomException>(
() => TryHandleElasticMappingError(dataGridResults, dataGridRecords),
MyFieldsCount)
.ConfigureAwait(false);

有没有可能是异步问题?上面的行包含在一个 Try-Catch 中,它捕获一个 Exception,我可以在其中验证异常的类型是 MyCustomException。我可以确认内部 catch block (重试方法中的那个)永远不会被命中。

最佳答案

Any chance it's an async-ness issue?

正如其他答案中所述,是的,这是一个异步问题。

C# 中的异步和迭代器 block 是协程。一个普通的例程可以做三件事:运行完成、抛出或进入无限循环。协程可以做第四件事:挂起,稍后恢复await 是异步 block 中发生挂起的点;它是迭代器 block 中的 yield return

在您的情况下,直到协程恢复才会发生抛出,此时 try 不再有效;带有try 的方法跑到完成 因为它不是协程。如果你想让 try 生效,那么 try 也必须在异步 block 中,并且你必须在 try 中 await .

同样,如果你写:

IEnumerable<int> Weird(bool b)
{
if (b) throw new Exception();
yield return 1;
}

...
IEnumerable<int> x = null;
try
{
x = Weird(true); // Should throw, right?
}
catch(Exception ex)
{
// Nope; this is unreachable
}
foreach(int y in x) // the throw happens here!

迭代器 block 协程开始挂起,直到在迭代器上调用 MoveNext 后才会恢复;它所做的只是返回一个迭代器。异步 block 协程在等待时挂起,但不需要在等待时挂起;允许等待已完成的任务以跳过暂停。

协程的 try-catch 很棘手;小心!

关于c# - 我可以捕获 C# 中泛型参数传入的类型的异常吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52102313/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com