Suppress warning CS1998: This async method lacks 'await'

前端 未结 14 940
遇见更好的自我
遇见更好的自我 2020-11-28 04:21

I\'ve got an interface with some async functions. Some of the classes that implements the interface does not have anything to await, and some might just throw. It\'s a b

相关标签:
14条回答
  • 2020-11-28 05:00

    I've got an interface with some async functions.

    Methods returning Task, I believe. async is an implementation detail, so it can't be applied to interface methods.

    Some of the classes that implements the interface does not have anything to await, and some might just throw.

    In these cases, you can take advantage of the fact that async is an implementation detail.

    If you have nothing to await, then you can just return Task.FromResult:

    public Task<int> Success() // note: no "async"
    {
      ... // non-awaiting code
      int result = ...;
      return Task.FromResult(result);
    }
    

    In the case of throwing NotImplementedException, the procedure is a bit more wordy:

    public Task<int> Fail() // note: no "async"
    {
      var tcs = new TaskCompletionSource<int>();
      tcs.SetException(new NotImplementedException());
      return tcs.Task;
    }
    

    If you have a lot of methods throwing NotImplementedException (which itself may indicate that some design-level refactoring would be good), then you could wrap up the wordiness into a helper class:

    public static class TaskConstants<TResult>
    {
      static TaskConstants()
      {
        var tcs = new TaskCompletionSource<TResult>();
        tcs.SetException(new NotImplementedException());
        NotImplemented = tcs.Task;
      }
    
      public static Task<TResult> NotImplemented { get; private set; }
    }
    
    public Task<int> Fail() // note: no "async"
    {
      return TaskConstants<int>.NotImplemented;
    }
    

    The helper class also reduces garbage that the GC would otherwise have to collect, since each method with the same return type can share its Task and NotImplementedException objects.

    I have several other "task constant" type examples in my AsyncEx library.

    0 讨论(0)
  • 2020-11-28 05:01

    Another way to preserve the async keyword (in case you want to keep it) is to use:

    public async Task StartAsync()
    {
        await Task.Yield();
    }
    

    Once you populate the method you can simply remove the statement. I use this a lot especially when a method might await something but not every implementation actually does.

    0 讨论(0)
  • 2020-11-28 05:01

    Try this:

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Await.Warning", "CS1998:Await.Warning")]

    See: https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.codeanalysis.suppressmessageattribute?view=netframework-4.7.2

    0 讨论(0)
  • 2020-11-28 05:01

    If you don't have anything to await then return Task.FromResult

    public Task<int> Success() // note: no "async"
    {
      ... // Do not have await code
      var result = ...;
      return Task.FromResult(result);
    }
    
    0 讨论(0)
  • 2020-11-28 05:05

    You can drop the async keyword from the method and just have it return Task;

        public async Task DoTask()
        {
            State = TaskStates.InProgress;
            await RunTimer();
        }
    
        public Task RunTimer()
        {
            return new Task(new Action(() =>
            {
                using (var t = new time.Timer(RequiredTime.Milliseconds))
                {
                    t.Elapsed += ((x, y) => State = TaskStates.Completed);
                    t.Start();
                }
            }));
        }
    
    0 讨论(0)
  • 2020-11-28 05:06

    I know this is an old thread, and perhaps this won't have the right effect for all usages, but the following is as close as I can get to being able to simply throw a NotImplementedException when I haven't yet implemented a method, without altering the method signature. If it's problematic I'd be happy to know about it, but it barely matters to me: I only use this while in development anyway, so how it performs isn't all that important. Still, I'd be happy to hear about why it's a bad idea, if it is.

    public async Task<object> test()
    {
        throw await new AwaitableNotImplementedException<object>();
    }
    

    Here's the type I added to make that possible.

    public class AwaitableNotImplementedException<TResult> : NotImplementedException
    {
        public AwaitableNotImplementedException() { }
    
        public AwaitableNotImplementedException(string message) : base(message) { }
    
        // This method makes the constructor awaitable.
        public TaskAwaiter<AwaitableNotImplementedException<TResult>> GetAwaiter()
        {
            throw this;
        }
    }
    
    0 讨论(0)
提交回复
热议问题