I posted this on stackoverflow as well (https://stackoverflow.com/questions/73948675/why-does-discarding-an-entityframework-firstordefaultasync-query-or-even-a-ora). But no one seems to have an answer for this other than "that should not be happening". Background is that I wanted to call "LONG_RUNNING_BACKGROUND_PROC" in our database without the client having to wait for its completion (it's a VERY long running background task and the client doesn't really need the result in that instance anyway).
But I immediatly noticed that _ = DbCallTestCommand()
instead behaved as if I had awaited it instead of
becoming fire and forget like what usually happens if you use the discard.
This is the code that shows this behaviour:
async Task Main()
{
"Main start!".Dump();
_ = DbCallTestCommand();
"Main Done!".Dump();
}
async Task DbCallTestCommand()
{
await using var connection = new OracleConnection(this.connectString);
await connection.OpenAsync();
await using var oracleCommand = new OracleCommand("", connection);
oracleCommand.CommandText = "LONG_RUNNING_BACKGROUND_PROC"; //<- long running statistic calculation job that the client shouldn't need to wait for.
oracleCommand.CommandType = CommandType.StoredProcedure;
await oracleCommand.ExecuteNonQueryAsync();
"DbCallTestCommand done".Dump();
}
async Task TaskDelayTest()
{
await Task.Delay(10000);
"TaskDelayTest done!".Dump();
}
If one instead swap _ = DbCallTestCommand()
with _ = TaskDelayTest()
then it behaves as expected. So does anyone know how awaiting command.ExecuteNonQueryAsync
is somehow able to alter the the behavour of the task/discard?
The only theory I have is that for some reason the task isn't really returned until ExecuteNonQueryAsync has finished it's processing. But I don't currently know of a way to confirm this.
I can fix this by using _ = Task.Run(() => DbCallTestCommand())
but that seems kinda wastefull, having to use 2 tasks instead of 1 when I'm not even interested in the result to begin with.