【发布时间】:2022-11-17 17:45:47
【问题描述】:
因为它真的像我期望的那样变成了火而忘记了。我需要在 Task.Run(() => DbCallTestCommand()) 中调用它,这对我来说似乎有点不必要?
这是在 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();
}
结果:
主线开始!
DbCallTest 命令!
主要完成!
这里的预期结果(恕我直言)是主要方法应该在丢弃的方法之前完成。因为我没有在 DbCallTestCommand() 上使用 await,但这不是这里发生的情况。
但是,如果我改为丢弃一个只等待 Task.Delay 的方法。方法。然后它按预期工作。 Main 方法在丢弃的方法之前完成。
看这里:
void Main()
{
"Main start!".Dump();
_ = TaskDelayTest();
"Main Done!".Dump();
}
async Task TaskDelayTest()
{
await Task.Delay(10000);
"TaskDelayTest done!".Dump();
}
结果:(这是丢弃任务的预期结果):
主线开始!
主要完成!
任务延迟测试完成!
我对此感到很困惑,我真的认为两个丢弃应该表现相同(即不要等待方法完成后再继续)。所以我想知道是否有人知道这样做的原因,这是否确实是正确的行为?
【问题讨论】:
-
看起来这两个链接是一样的。有些方法只能异步完成。使用 FirstOrDefault 将在仅返回一个结果时更快地终止查询,而不是等到找到所有结果。
-
我使用图像是因为我也想展示我得到的结果。但我会改变它!
-
不要使用
await Task.Delay(1);。相反,删除async关键字并返回Task.FromResult()或对于没有返回类型的方法,Task.CompletedTask -
@EricJ 我已经更改了上面的代码以尽量避免混淆。但是 main 方法是否异步并不重要。如果您尝试丢弃等待 dbCommand 异步方法的异步方法(例如
await command.ExecuteNonQueryAsync),丢弃仍然不会按预期运行。
标签: c# asynchronous .net-6.0