简体   繁体   English

将 function 标记为异步但没有等待调用,有什么问题吗?

[英]Marking a function as async but no await calls, any issues?

Are there any side effects to having a function that is marked as async, but it doesn't actually make any await calls?标记为异步的 function 是否有任何副作用,但它实际上并没有进行任何等待调用? Eg:例如:

public interface IMyInterface
{
    Task DoSomethingAsync();
}

public class DoSomething1:IMyInterface
{
    public async Task DoSomethingAsync()
    {
        await getSomethingFromDatabaseAsync();
    }
}

public class DoSomething2:IMyInterface
{
    public async Task DoSomethingAsync()
    {
        doSomethingElse();
    }
}

IMyInterface is implemented by quite a few classes, but for one of the classes there are no await calls. IMyInterface 由很多类实现,但其中一个类没有等待调用。 Will this cause any problems?这会导致任何问题吗?

In the case where you have an interface method that returns a task and you have no awaits (yeah it happens).如果您有一个返回任务的接口方法并且您没有等待(是的,它发生了)。 Just remove the async keyword and return Task.CompletedTask只需删除async关键字并返回Task.CompletedTask

The Task.CompletedTask property returns a task whose Status property is set to RanToCompletion . Task.CompletedTask属性返回其Status属性设置为RanToCompletion的任务。

Gets a task that has already completed successfully.获取已成功完成的任务。

public class DoSomething2:IMyInterface
{
    public Task DoSomethingAsync()
    {
        doSomethingElse();
        return Task.CompletedTask;
    }
}

Yes there are side affects, the compiler is plumbing up the IAsyncStateMachine and produces a bunch more IL , additionally future developers will look at your code with ire .是的,有副作用,编译器正在调试 IAsyncStateMachine 并产生更多IL ,另外未来的开发人员将使用ire查看您的代码。 As for other functional differences, I can't think of any off hand.至于其他功能上的差异,我想不出任何副手。

IMyInterface is implemented by quite a few classes, but for one of the classes there are no await calls. IMyInterface 由相当多的类实现,但其中一个类没有 await 调用。 Will this cause any problems?这会导致任何问题吗?

I'm going to enter dangerous territory here and disagree with Eric Lippert.我要在这里进入危险的领域,不同意埃里克·利珀特的观点。 In the vast majority of cases, using async without await is indeed a mistake and the compiler warning is useful.在绝大多数情况下,在没有await的情况下使用async确实是一个错误,编译器警告很有用。 I'd say this is true well north of 90% of the time.我会说这在 90% 的时间以北都是正确的。

However, I'd say this scenario is an exception to that rule.但是,我想说这种情况是该规则的一个例外。 The problem with just dropping async / await is that exceptions are handled quite differently:仅删除async / await的问题在于异常的处理方式完全不同:

public Task DoSomethingAsync()
{
  // if doSomethingElse throws, that exception is raised directly;
  // it is *not* captured and placed on the returned task!
  doSomethingElse();
  return Task.CompletedTask;
}

The expected semantics for a Task -returning method is that exceptions are captured and placed on the returned Task (well, at least non- bone-headed exceptions). Task返回方法的预期语义是捕获异常并将其放置在返回的Task (好吧,至少是非头骨异常)。 To keep these semantics, you need to either use async (and suppress the warning) or an explicit try / catch :为了保持这些语义,您需要使用async (并抑制警告)或显式try / catch

#pragma warning disable 1998
public async Task DoSomethingAsync()
#pragma warning restore 1998
{
  doSomethingElse();
}

// or

public Task DoSomethingAsync()
{
  try
  {
    doSomethingElse();
    return Task.CompletedTask;
  }
  catch (Exception ex)
  {
    return Task.FromException(ex);
  }
}

In your case, I think there might be a problem of blocking the main thread (and it depends if you care or not) and I think this is not a developer wants.在您的情况下,我认为可能存在阻塞主线程的问题(这取决于您是否关心)并且我认为这不是开发人员想要的。

If you do not have any await calls, you can do the below so that the main thread will not be blocked (> .net 4.0):如果您没有任何 await 调用,您可以执行以下操作,以免主线程被阻塞(> .net 4.0):

public class DoSomething2:IMyInterface
{
     public async Task DoSomethingAsync()
     {
         await Task.Run(()=>doSomethingElse());
     }
}

Methods marked as async will work the same way it will just create a bit overhead, because when method is marked as async compiler basically generates state machine for that method.( which in your case wont be use in some particular methods )标记为 async 的方法将以相同的方式工作,它只会产生一点开销,因为当方法被标记为 async 编译器时,基本上会为该方法生成状态机。(在您的情况下不会在某些特定方法中使用)

https://foreverframe.net/what-lies-beneath-asyncawait-in-c/ https://foreverframe.net/what-lies-beneath-asyncawait-in-c/

https://msdn.microsoft.com/en-us/magazine/jj991977.aspx https://msdn.microsoft.com/en-us/magazine/jj991977.aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM