禁止警告CS1998:这种asynchronous方法缺less“等待”
我有一些asynchronous函数的接口。 一些实现接口的类没有什么可以等待的,有些可能只是抛出。 所有的警告都有点烦人
在不使用asynchronousfunction时等待。
是否可以压制消息?
public async Task<object> test() { throw new NotImplementedException(); }
警告CS1998:这种asynchronous方法缺less“等待”操作员,并将同步运行。 考虑使用'await'操作符来等待非阻塞API调用,或者'等待Task.Run(…)'在后台线程上执行CPU绑定的工作。
我有一些asynchronous函数的接口。
方法返回Task
,我相信。 async
是一个实现细节,所以它不能应用于接口方法。
一些实现接口的类没有什么可以等待的,有些可能只是抛出。
在这些情况下,您可以利用async
是实现细节的事实。
如果你没有什么可以await
,那么你可以返回Task.FromResult
:
public Task<int> Success() // note: no "async" { ... // non-awaiting code int result = ...; return Task.FromResult(result); }
在抛出NotImplementedException
的情况下,过程有点罗嗦:
public Task<int> Fail() // note: no "async" { var tcs = new TaskCompletionSource<int>(); tcs.SetException(new NotImplementedException()); return tcs.Task; }
如果你有很多方法抛出NotImplementedException
(这本身可能表明一些devise级重构是好的),那么你可以把这个单词包装到一个辅助类中:
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; }
helper类还减less了GC本来需要收集的垃圾,因为具有相同返回types的每个方法可以共享其Task
和NotImplementedException
对象。
我在AsyncEx库中有几个其他的“任务常量”types的例子 。
另一个select是,如果你想保持函数的主体简单而不需要编写代码来支持它,只需要用#pragma来压制警告:
#pragma warning disable 1998 public async Task<object> Test() { throw new NotImplementedException(); } #pragma warning restore 1998
如果这很常见,可以将disable语句放在文件的顶部,并省略恢复。
http://msdn.microsoft.com/en-us/library/441722ys(v=vs.110).aspx
另一种保存async关键字的方法是(如果你想保留的话)是使用:
public async Task StartAsync() { await Task.Yield(); }
一旦你填充该方法,你可以简单地删除该语句。 我特别使用这个方法,特别是当一个方法可能等待某些事情,但并不是每个实现都实际执
我知道这是一个旧的线程,也许这不会对所有的用法都有正确的效果,但是下面是我可以简单地抛出一个NotImplementedException,当我还没有实现一个方法,而不改变方法签名。 如果有问题,我很乐意知道,但对我来说几乎没有什么问题,无论如何我只是在开发中使用它,所以它的performance并不是那么重要。 不过,如果是的话,我很乐意听到为什么这是一个坏主意。
public async Task<object> test() { throw await new AwaitableNotImplementedException<object>(); }
这是我为增加可能性而添加的types。
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; } }
就像Stephen's Answer的一个更新一样,你不再需要编写TaskConstants
类,因为有一个新的辅助方法:
return Task.FromException(new NotImplementedException());
如果您已经与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(); }
反应式和asynchronous式/等待式都是独一无二的,但它们也能很好地结合在一起。
包括需要的是:
using System.Reactive.Linq; using System.Reactive.Threading.Tasks;
下面可能会出现cs1998。
public async Task<object> Foo() { return object; }
那么你可以在下面改革。
public async Task<object> Foo() { var result = await Task.Run(() => { return object; }); return result; }
// This is to get rid of warning CS1998, please remove when implementing this method. await new Task(() => { }).ConfigureAwait(false); throw new NotImplementedException();
如果你没有任何东西要等待,那么返回Task.FromResult
public Task<int> Success() // note: no "async" { ... // Do not have await code var result = ...; return Task.FromResult(result); }
你可以从方法中删除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(); } })); }