为什么 C# 中的异步调用需要这样声明,如果它们所在的方法已经用 'async' 关键字声明?
Why do asynchronous calls in C# need to be declared as such if the method they reside in is declared with the 'async' keyword already?
现在,我发现的这个 "nitpick" 有 99% 的可能性完全是由于我自己的无知 - 我是一名初级 Web 开发人员,只是偶尔接触 C# 几个月,所以我提前为我的问题可能的愚蠢道歉。我的大部分经验是使用 PHP 和 JS。
如果我有一个使用 async
关键字声明的方法:
public async Task<ActionResult> Create(MyObject myObject)
{
}
为什么我还必须像这样明确指定 LINQ 语句是异步的:
public async Task<ActionResult> Create(MyObject myObject)
{
if (ModelState.IsValid)
{
myObject.Id = Guid.NewGuid();
myObject.DisplayId = await db.MyObjects.MaxAsync(m => m.DisplayId) + 1;
db.MyObjects.Add(myObject);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(myObject);
}
难道 C# 编译器不能足够聪明地弄清楚因为该方法是异步的,所以我想在该方法中执行的 LINQ 语句也应该是异步的吗?
我想我真正的不满是现在大多数 LINQ 方法都有一个异步孪生(SaveChangesAsync
、MaxAsync
、FirstOrDefaultAsync
),我必须使用 await
关键字每次我想执行这样的调用。这似乎过于冗长和不必要。
如果仍然需要对调用的同步性进行精细控制,为什么 C# 开发人员不简单地允许我使用 .Await()
、.Async()
或 Sync()
方法可以追加吗?
Can't the C# compiler be clever enough to figure out that because the method is asynychronous, the LINQ statements I want to execute within the method should be asynchronous too?
如果想在异步方法中进行同步调用怎么办?
您希望同一方法是同步的还是异步的,这取决于您是否处于异步方法中?我想一种语言可以做到这一点,但它需要一个根本不同的模型,而不是 C# 使用的模型。另外,我不确定这是个好主意;这可能很混乱。最好让事情明确 IMO。
I guess my real beef with this is that there's now an asynchronous twin for most LINQ methods (SaveChangesAsync, MaxAsync, FirstOrDefaultAsync), and I have to use the await keyword every time I want to execute such calls. It seems excessively verbose and unnecessary.
使用或不使用await
没有相同的含义。如果你不使用 await
,你只是检索任务,这在某些情况下很有用(例如,如果你想并行化任务。例如,考虑以下内容:
Task t1 = SomeAsyncOperation();
Task t2 = SomeOtherAsyncOperation();
await Task.WhenAll(t1, t2);
在上面的代码中,运行 操作是并行的。现在,如果您在每次调用时都使用 await:
await SomeAsyncOperation();
await SomeOtherAsyncOperation();
操作现在是顺序的。
开发人员需要控制这种事情。这就是 await
不能隐式的原因,因为它改变了代码的行为。
If granular control over the synchronicity of the call was still needed, why didn't the C# developers simply allow for an .Await() or .Async() method that I could append?
.Await()
方法如何比关键字更好?无论如何,这是行不通的。使用 await
关键字将方法体转换为状态机;方法调用无法做到这一点。
await
完全改变了方法代码的生成方式——状态机与线性代码——所以你不能用任何自定义的 .Await()
方法神奇地实现它,因为方法调用编译成线性码。
C# 通常选择显式方法而不是神奇地猜测意图 - 所以虽然在某些情况下编译器可能会猜测需要 await
调用但它不会。
请注意,var
通常也无法做出猜测:
var displayId = db.MyObjects.MaxAsync(m => m.DisplayId);
displayId
可能是 Task
或者如果编译器允许猜测丢失的 await
它可能是 int
。
现在,我发现的这个 "nitpick" 有 99% 的可能性完全是由于我自己的无知 - 我是一名初级 Web 开发人员,只是偶尔接触 C# 几个月,所以我提前为我的问题可能的愚蠢道歉。我的大部分经验是使用 PHP 和 JS。
如果我有一个使用 async
关键字声明的方法:
public async Task<ActionResult> Create(MyObject myObject)
{
}
为什么我还必须像这样明确指定 LINQ 语句是异步的:
public async Task<ActionResult> Create(MyObject myObject)
{
if (ModelState.IsValid)
{
myObject.Id = Guid.NewGuid();
myObject.DisplayId = await db.MyObjects.MaxAsync(m => m.DisplayId) + 1;
db.MyObjects.Add(myObject);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(myObject);
}
难道 C# 编译器不能足够聪明地弄清楚因为该方法是异步的,所以我想在该方法中执行的 LINQ 语句也应该是异步的吗?
我想我真正的不满是现在大多数 LINQ 方法都有一个异步孪生(SaveChangesAsync
、MaxAsync
、FirstOrDefaultAsync
),我必须使用 await
关键字每次我想执行这样的调用。这似乎过于冗长和不必要。
如果仍然需要对调用的同步性进行精细控制,为什么 C# 开发人员不简单地允许我使用 .Await()
、.Async()
或 Sync()
方法可以追加吗?
Can't the C# compiler be clever enough to figure out that because the method is asynychronous, the LINQ statements I want to execute within the method should be asynchronous too?
如果想在异步方法中进行同步调用怎么办?
您希望同一方法是同步的还是异步的,这取决于您是否处于异步方法中?我想一种语言可以做到这一点,但它需要一个根本不同的模型,而不是 C# 使用的模型。另外,我不确定这是个好主意;这可能很混乱。最好让事情明确 IMO。
I guess my real beef with this is that there's now an asynchronous twin for most LINQ methods (SaveChangesAsync, MaxAsync, FirstOrDefaultAsync), and I have to use the await keyword every time I want to execute such calls. It seems excessively verbose and unnecessary.
使用或不使用await
没有相同的含义。如果你不使用 await
,你只是检索任务,这在某些情况下很有用(例如,如果你想并行化任务。例如,考虑以下内容:
Task t1 = SomeAsyncOperation();
Task t2 = SomeOtherAsyncOperation();
await Task.WhenAll(t1, t2);
在上面的代码中,运行 操作是并行的。现在,如果您在每次调用时都使用 await:
await SomeAsyncOperation();
await SomeOtherAsyncOperation();
操作现在是顺序的。
开发人员需要控制这种事情。这就是 await
不能隐式的原因,因为它改变了代码的行为。
If granular control over the synchronicity of the call was still needed, why didn't the C# developers simply allow for an .Await() or .Async() method that I could append?
.Await()
方法如何比关键字更好?无论如何,这是行不通的。使用 await
关键字将方法体转换为状态机;方法调用无法做到这一点。
await
完全改变了方法代码的生成方式——状态机与线性代码——所以你不能用任何自定义的 .Await()
方法神奇地实现它,因为方法调用编译成线性码。
C# 通常选择显式方法而不是神奇地猜测意图 - 所以虽然在某些情况下编译器可能会猜测需要 await
调用但它不会。
请注意,var
通常也无法做出猜测:
var displayId = db.MyObjects.MaxAsync(m => m.DisplayId);
displayId
可能是 Task
或者如果编译器允许猜测丢失的 await
它可能是 int
。