For it to actually become fire and forget as I expect it to. I'll need to call it inside a Task.Run(() => DbCallTestCommand())
instead which seems a bit unnecessary to me?
This is an example code that reproduced the issue in LINQPad:
void Main()
{
"Main start!".Dump();
_ = DbCallTestCommand();
"Main Done!".Dump();
}
//Makes no sense to really execute this as a fire and forget but I included it because Im guessing that EF also uses DbCommand behind the scenes.
async Task DbCallTestEF()
{
var db = new EventContext(this.connectString);
var query = db.TBLEVENT.Where(t => t.STARTDATE > DateTime.Now.AddDays(-65));
var result = await query.ToListAsync(); //Takes about 10 seconds to run in total
"DbCallTestEF done".Dump();
}
async Task DbCallTestCommand()
{
using var connection = new OracleConnection(this.connectString);
await connection.OpenAsync();
using var command = connection.CreateCommand();
command.CommandText = "UPDATE_STATISTICS"; //<- long running statistic calculation job that the client shouldn't need to wait for.
command.CommandType = CommandType.StoredProcedure;
await command.ExecuteNonQueryAsync();
"DbCallTestCommand done".Dump();
}
Result:
Main Start!
DbCallTestCommand!
Main Done!
The expected result here (imho) is that the main method should complete BEFORE the discarded method. Because I didn't use an await on DbCallTestCommand() but that is not what happens here.
However if I instead discard a method that simply just awaits a Task.Delay
. method. Then it works as expected. Main method completes before discarded method.
See here:
void Main()
{
"Main start!".Dump();
_ = TaskDelayTest();
"Main Done!".Dump();
}
async Task TaskDelayTest()
{
await Task.Delay(10000);
"TaskDelayTest done!".Dump();
}
Result: (which is the expected result for discarding a task):
Main Start!
Main Done!
TaskDelayTest done!
I'm quite stumped by this and I really think both discards should behave the same (i.e to NOT wait for the methods completion before continuing). So I'm wondering if anyone knows the reason for this and if this is indeed the correct behaviour?