2016-06-22 29 views
0

我有一个任务来清理编译器警告的项目。目前我正在研究用于ASP.NET和Xamarin解决方案的cs文件。在那里,我有一个方法:使用预处理指令在异步方法中抛出异常

public override async SomeReturnTypeItem LoginAsync() 
    { 
#if __MOBILE__ 
     throw new NotSupportedException("Windows authentication is not supported in mobile version"); 
#endif 
    //some code 
    } 

在Xamarin的解决方案我有#endif下一个警告代码不可达。如果我将#endif替换为#else并将#endif置于方法末尾,我会收到警告,该方法缺少await运算符并将同步运行。我如何使这种方法免于警告?

+1

你期望什么?如果设置了__MOBILE__,那么代码*是不可访问的 - 一个异常和它不会执行后的任何代码。如果您不想要警告,请删除代码或使用'#else'指令 –

+1

如果您收到警告“方法缺乏等待操作符”,则根本不应该有'async'关键字,它适用于两个版本。 –

+0

我是否安全地假设“某些代码”包含“await”? –

回答

0

我使用的解决方案是欺骗编译器。

public override async SomeReturnTypeItem LoginAsync() 
    { 
#if __MOBILE__ 
     bool isMobile = true; 
     if (isMobile) 
     { 
      throw new NotSupportedException("Windows authentication is not supported in mobile version"); 
     } 
#endif 
     //some async code 
    } 

Visual Stuidio表示异步代码启发式无法访问,但编译器满意。当然,它有点难看,但它有效。不过谢谢你们试图帮助)

0

它有点丑陋,但你可以这样做:

public override 
#if !__MOBILE__ 
    async 
#endif 
    SomeReturnTypeItem LoginAsync() { 
#if __MOBILE__ 
    throw new NotSupportedException("Windows authentication is not supported in mobile version"); 
#else 
    //some code 
#endif 
    } 

这是假设你确实有await关键字在某处“一些代码”。如果不是,那么你应该删除async

或者,你可以简单地用一个#pragma指令来抑制警告: #pragma warning

+0

问题不是'async',它是'throw' *之后的任何代码*无法访问 –

+0

@PanagiotisKanavos它意味着与他的修改一起使用:使用'#else ...#endif'。我已经编辑过,以便更清晰。 –

2

最简单的解决将是

public override async SomeReturnTypeItem LoginAsync() 
{ 
#if __MOBILE__ 
    throw new NotSupportedException("Windows authentication is not supported in mobile version"); 
#else 
    //some code using await 
#endif 
} 

但是这可能不完全是你想要的行为,因为如果__MOBILE__ 是定义,该方法将返回故障Task而不是立即投掷。这种差异有时会证明非常大,大多数情况下,如果您将Task存储起来供以后使用,而不是立即等待(例如,如果要启动多个任务并让它们同时运行)。

为了解决这个问题,你应该把在方法的异常抛出代码和异步执行的另一个:

public override SomeReturnTypeItem LoginAsync() 
{ 
#if __MOBILE__ 
    throw new NotSupportedException("Windows authentication is not supported in mobile version"); 
#else 
    return LoginAsyncImpl(); 
#endif 
} 

private async SomeReturnTypeItem LoginAsync() 
{ 
    //some code using await 
} 

当然,如果你不使用await可言,你只是不应该首先将您的方法标记为async

public override omeReturnTypeItem LoginAsync() 
{ 
#if __MOBILE__ 
    throw new NotSupportedException("Windows authentication is not supported in mobile version"); 
#else 
    //some code not using await 
#endif 
} 

请注意,非异步代码仍然可以返回Task。例如,如果您实现了一个接口或基类,这些接口或基类使一些方法返回任务,以便实现可以真正异步,但您的具体实现恰好是同步的,那么这很有用。

public override Task SomeMethodAsync() 
{ 
    // do some synchronous stuff 
    return Task.FromResutl(true); 
} 
+0

我认为这个答案的第二部分是最好的解决方案。 – Neil

+0

但是第一部分是错误的(或不完整),因为正如问题中提到的那样,他已经尝试过了,它给出了不同的警告。 –

相关问题