等同于ConditionalAttribute for Task返回异步方法

时间:2017-05-15 08:45:42

标签: c# .net asynchronous async-await

我想写一个async方法,但我希望只有在使用特定的编译常量编译程序集时才能调用它。

ONE WAY

我能做到的一种方法是使用pragma指令,即条件编译常量,如下所示:

// Callee
#if FOO
  public async Task DoFooAsync()
  {
    ...
  }
#end if

// Caller 1
#if Foo
  // fire and forget
  DoFooAsync();
#endif

// Caller 2
#if Foo
  public async Task<T> DoWork<T>()
  {
    T returnValue = default(T);

    // fire but don't forget
    var fooTask = DoFooAsync();

    // Prepare return value
    returnValue = ...;

    // Not terribly important but what if the caller wants
    // to find out
    if (fooTask.Status == Faulted)
    {
       // do something about it
    }
  }
#endif

正如你所看到的,编写所有这些内容会非常混乱。

另一种方式

另一种方法是使用ConditionalAttribute。但是,通过阅读文档,该属性似乎仅适用于返回void的方法。

如果没有那个约束,我会很容易地使用这个属性,这会让代码变得更整洁,更好看和阅读:

// Callee
[Conditional("FOO")]
public Task DoFooAsync() { ... }

// Caller
public async Task<T> DoWork<T>()
{
  // fire and forget
  DoFooAsync();

  // fire but would like to know what happened
  var fooTask = DoFooAsync();

  T t = GetTee();

  if (fooTask.IsFaulted) { ... }

  return t;  

}

虽然我可以让我的async方法返回void而不是Task,但我对此感到非常不舒服。

那么,对于想要返回值的方法,是否有等效的ConditionalAttribute?是否至少有一个方法只想返回Task

1 个答案:

答案 0 :(得分:2)

如果你按照自己的条件进行编译,你会发生什么?它应该返回null吗?还是完成了任务?或者任务失败?

可能的解决方案是编写这样的异步方法:

#if FOO
public Task DoFooAsync() => Task.FromResult(0);
#else 
public Task DoFooAsync()
{
    //...
}
#endif

因此,如果使用条件符号编译程序集,则调用者将获得空任务。