Why does the following code cause a StackOverflowException in .Net4.8 with only a 17-depth recursion? However this does not happen in NetCore 3.1 (I can set the count to 10_000 and it still works)
class Program
{
static async Task Main(string[] args)
{
try
{
await TestAsync(17);
}
catch(Exception e)
{
Console.WriteLine("Exception caught: " + e);
}
}
static async Task TestAsync(int count)
{
await Task.Run(() =>
{
if (count <= 0)
throw new Exception("ex");
});
Console.WriteLine(count);
await TestAsync2(count);
}
static async Task TestAsync2(int count) => await TestAsync3(count);
static async Task TestAsync3(int count) => await TestAsync4(count);
static async Task TestAsync4(int count) => await TestAsync5(count);
static async Task TestAsync5(int count) => await TestAsync6(count);
static async Task TestAsync6(int count) => await TestAsync(count - 1);
}
Is this a known bug in .Net 4.8? I would except a lot more than 17 levels of recursion in such a function... Does this effectively mean writing recursions with async/await is not recommended?
Update: Simplified version
class Program
{
// needs to be compiled as AnyCpu Prefer 64-bit
static async Task Main(string[] args)
{
try
{
await TestAsync(97); // 96 still works
}
catch(Exception e)
{
Console.WriteLine("Exception caught: " + e);
}
}
static async Task TestAsync(int count)
{
await Task.Run(() =>
{
if (count <= 0)
throw new Exception("ex");
});
Console.WriteLine(count);
await TestAsync(count-1);
}
}
It only happens so fast when choosing Any Cpu with Prefer 32-bit disabled, but is reproducable on multiple machines (Windows 1903 and 1909) on multiple .net versions (.Net 4.7.2 and .Net 4.8)
count < 0
. But inTestAsync6
you callTestAsync
withcount-1
. No matter if you start with 17 or 2 or whatever, sooner or later you call it with-1
and then get the exception. I'd say it's expected. – Strenuouscount <= 0
, and this is fine when calling it with say2
than it will throw and the exception will be caught and everything is fine, however when calling with17 or higher
the exception will be thrown but will in turn cause a stack overflow exception which is what i did not expect... – LodhiaStackOverflowException
. Check it out: #61102665 – Internationalismawait TestAsync(235);
in .NET Framework 4.8. But at this point it's kind of expected. – Octangular