没有Await的异步编程

本文关键字:编程 异步 Await 没有 | 更新日期: 2023-09-27 18:15:38

我正在研究一系列使用实体框架执行许多不同数据库调用的方法。这些方法中的许多方法可以异步运行,因为我真的不关心它们的输出,也不依赖它们。

然而,当我尝试实现某些方法时,我从编译器得到一个警告说:"因为这个调用没有等待,当前方法在调用完成之前继续运行"

但对我来说,这似乎是我想要的行为,因为我不在乎方法做什么。

下面是一个方法

的例子
public async Task SetupAccessControl(int objectTypeId, int objectId, int? organizationId)
{
    using (var context = new SupportContext(CustomerId))
    {
        ... // omitted for brevity
        if (objectTypeId == (int) ObjectType.User)
        {
            AddToUserRoleBridge("Everyone", objectId);//Warning on this line
            AddToUserRoleBridge("Default", objectId); //Warning on this line
        }
        ... // omitted for brevity
    }
}
public async Task AddToUserRoleBridge(string role, int userId)
{
    using (var context = new SupportContext(CustomerId))
    {
        var defaultRole = context.Roles.FirstOrDefault(n => n.Name == role);
        if (defaultRole != null)
        {
            var urb = new UserRoleBridge
            {
                RoleId = defaultRole.Id,
                UserId = userId
            };
            context.UserRoleBridges.Add(urb);
            await context.SaveChangesAsync();
        }
    }
} 

编辑

本质上,当我运行main函数时,我希望一系列方法调用能够同时启动,并在它们自己的线程中处理所有内容,这样我就不必担心它。下面是一个伪代码示例。

public async void RunAllAsync() {
    taskA(*some value*);
    taskA(*some value*);
    taskB(*some value*);
    taskB(*some value*);
    await AllTasksCompleted
}
public async Task taskA(int item){
     //do something with item
}

public async Task taskB(int item) {
    subTaskB(*some value*)
    subTaskB(*some value*)
}
public async Task subTaskB(int item) {
    // do something
} 

在上面的例子中,当#RunAllAsync被调用时,它所做的每个函数调用(以及它们所做的函数调用)都被同时触发。当所有这些调用完成后,调用#RunAllAsync的方法将继续执行。

没有Await的异步编程

如果您不使用await,则async关键字并没有真正做任何有用的事情,您可以将其关闭。你可以等待一个返回Task的方法,不管它是否被标记为async。

public Task DoSomethingAsync()
{
    Task someTaskJustLikeANormalReturnValue = Task.Delay(1000);
    return someTaskJustLikeANormalReturnValue;
}
// later...
public async Task SomeOtherFunction()
{
    // You can await DoSomethingAsync just like any async method, because
    // you're really awaiting the Task which got returned.
    await DoSomethingAsync();
}

在你的情况下,我可能会收集任务并等待它们在一起:

    public async Task SetupAccessControl(int objectTypeId, int objectId, int? organizationId)
    {
        var tasks = new List<Task>();
        using (var context = new SupportContext(CustomerId))
        {
            ... // omitted for brevity
            if (objectTypeId == (int) ObjectType.User)
            {
                tasks.Add(AddToUserRoleBridge("Everyone", objectId));
                tasks.Add(AddToUserRoleBridge("Default", objectId));
            }
            ... // omitted for brevity
        }
        await Task.WhenAll(tasks.ToArray());
    }

这允许您将是否等待子任务的决定传递给调用者。这也将允许任何调用者打开任何异常,如果他们发生在AddToUserRoleBridge

有两种方法:

  • 修改AddToUserRoleBridge的签名为返回void will删除警告(但没有什么可以等待它)。
  • 保存呼叫结果。var ignoreme=AddToUserRoleBridge(...)也将删除警告。