C# 抑制警告 CS1998:此异步方法缺少“等待”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13243975/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 07:54:25  来源:igfitidea点击:

Suppress warning CS1998: This async method lacks 'await'

c#asynchronous

提问by Simon

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 bit annoying with all the warnings.

我有一个带有一些异步功能的接口。一些实现接口的类没有任何等待,而有些可能只是抛出。所有的警告都有点烦人。

When not using await in a async function.

在异步函数中不使用 await 时。

Is it possible to suppress the message?

是否可以抑制消息?

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

warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

警告 CS1998:此异步方法缺少“await”运算符,将同步运行。考虑使用 'await' 运算符来等待非阻塞 API 调用,或使用 'await Task.Run(...)' 在后台线程上执行 CPU 密集型工作。

采纳答案by Stephen Cleary

I've got an interface with some async functions.

我有一个带有一些异步功能的接口。

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

方法返回Task,我相信。async是一个实现细节,所以它不能应用于接口方法。

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 asyncis an implementation detail.

在这些情况下,您可以利用async实现细节这一事实。

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

如果您无事可做await,那么您可以返回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:

在 throwing 的情况下NotImplementedException,过程有点冗长:

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:

如果你有很多方法抛出NotImplementedException(这本身可能表明一些设计级重构会很好),那么你可以将冗长的内容包装到一个辅助类中:

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 Taskand NotImplementedExceptionobjects.

helper 类还减少了 GC 否则必须收集的垃圾,因为具有相同返回类型的每个方法都可以共享其TaskNotImplementedException对象。

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

我的 AsyncEx 库中有其他几个“任务常量”类型示例

回答by John

In case you already link against Reactive Extension, you can also do:

如果您已经链接到 Reactive Extension,您还可以执行以下操作:

public async Task<object> NotImplemented()
{
    await Observable.Throw(new NotImplementedException(), null as object).ToTask();
}

public async Task<object> SimpleResult()
{
    await Observable.Return(myvalue).ToTask();
}

Reactive and async/await are both amazing in and by themselves, but they also play well together.

Reactive 和 async/await 本身和本身都很棒,但它们也能很好地协同工作。

Includes needed are:

需要的包括:

using System.Reactive.Linq;
using System.Reactive.Threading.Tasks;

回答by Jamie Macia

Another option, if you want to keep the body of the function simple and not write code to support it, is simply to suppress the warning with #pragma:

另一种选择,如果您想保持函数体简单而不编写代码来支持它,只需使用 #pragma 抑制警告:

#pragma warning disable 1998
public async Task<object> Test()
{
    throw new NotImplementedException();
}
#pragma warning restore 1998

If this is common enough, you could put the disable statement at the top of the file and omit the restore.

如果这足够常见,您可以将禁用语句放在文件顶部并省略还原。

http://msdn.microsoft.com/en-us/library/441722ys(v=vs.110).aspx

http://msdn.microsoft.com/en-us/library/441722ys(v=vs.110).aspx

回答by Simon Mattes

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

保留 async 关键字的另一种方法(如果您想保留它)是使用:

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.

填充该方法后,您可以简单地删除该语句。我经常使用它,特别是当一个方法可能等待某些东西但不是每个实现实际上都这样做时。

回答by rrreee

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.

我知道这是一个旧线程,也许这不会对所有用法都产生正确的效果,但是以下内容与在我尚未实现方法时能够简单地抛出 NotImplementedException 一样接近,不改变方法签名。如果它有问题,我很高兴知道它,但对我来说几乎不重要:无论如何我只在开发时使用它,所以它的性能并不是那么重要。不过,我很高兴听到为什么这是一个坏主意,如果是的话。

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;
    }
}

回答by u6563376

It might be occured cs1998 below.

下面的 cs1998 可能会发生这种情况。

public async Task<object> Foo()
{
    return object;
}

Then you can reform below.

那么你可以在下面进行改造。

public async Task<object> Foo()
{
    var result = await Task.Run(() =>
    {
        return object;
    });
    return result;
}

回答by bkoelman

// This is to get rid of warning CS1998, please remove when implementing this method.
await new Task(() => { }).ConfigureAwait(false);
throw new NotImplementedException();

回答by Rakz

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

您可以从方法中删除 async 关键字并让它返回 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();
            }
        }));
    }

回答by Matt

Just as an update to Stephen's Answer, you no longer need to write the TaskConstantsclass as there is a new helper method:

就像对 Stephen's Answer 的更新一样,您不再需要编写TaskConstants该类,因为有一个新的辅助方法:

    public Task ThrowException()
    {
        try
        {
            throw new NotImplementedException();
        }
        catch (Exception e)
        {
            return Task.FromException(e);
        }
    }

回答by priyanka

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

如果您没有任何等待,则返回 Task.FromResult

public Task<int> Success() // note: no "async"
{
  ... // Do not have await code
  var result = ...;
  return Task.FromResult(result);
}