[英]Throwing exception in async method with preprocessor directive
I have a task to clean the project of compiler's warnings. 我的任务是清理项目的编译器警告。 Currently I am working on cs file that is used in solutions for ASP.NET and Xamarin.
目前,我正在研究用于ASP.NET和Xamarin解决方案的CS文件。 There I have a method:
那里我有一个方法:
public override async SomeReturnTypeItem LoginAsync()
{
#if __MOBILE__
throw new NotSupportedException("Windows authentication is not supported in mobile version");
#endif
//some code
}
In Xamarin solution I have a warning that code under #endif
is unreachable. 在Xamarin解决方案中,我警告
#endif
下的代码不可访问。 If I replace #endif
with #else
and put #endif
to the end of method, I receive a warning that method lacks await
operator and will run synchronously. 如果将
#endif
替换为#else
并将#endif
放在方法末尾,则会收到一条警告,提示该方法缺少await
运算符,并且将同步运行。 How can I make this method free of warnings? 如何使该方法没有警告?
The simplest fix would be 最简单的解决方法是
public override async SomeReturnTypeItem LoginAsync()
{
#if __MOBILE__
throw new NotSupportedException("Windows authentication is not supported in mobile version");
#else
//some code using await
#endif
}
But that's probably not exactly the behaviour you want, because if __MOBILE__
is defined, the method will return a faulted Task
instead of throwing right away. 但这可能不完全是您想要的行为,因为如果定义了
__MOBILE__
,则该方法将返回错误的Task
而不是立即抛出。 The difference can sometimes prove very big, mostly if you store the Task
for later use instead of awaiting it right away (for instance if you want to start several tasks and let them run concurrently). 有时差异可能会非常大,主要是如果您存储
Task
以备后用而不是立即等待(例如,如果您要启动多个任务并让它们同时运行),则差异很大。
To remedy this, you should put the exception throwing code in a method and the async implementation in another: 为了解决这个问题,您应该将抛出异常的代码放在一个方法中,并将异步实现放在另一个方法中:
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
}
Of course, if you're not using await
at all, you just shouldn't mark your method as async
in the first place! 当然,如果您根本不使用
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
}
Note that a non-async code can still return a Task
. 请注意,非异步代码仍然可以返回
Task
。 That's useful for instance if you implement an interface or base class that make some methods return task so that the implementation could be really asynchronous, but your specific implementation happens to be synchronous. 例如,如果您实现一个使某些方法返回任务的接口或基类,以便该实现实际上是异步的,但您的特定实现恰好是同步的,则这很有用。
public override Task SomeMethodAsync()
{
// do some synchronous stuff
return Task.FromResutl(true);
}
It's kinda ugly, but you could do this: 这有点丑陋,但是您可以这样做:
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
}
This is assuming you actually have the await
keyword somewhere in "some code". 这是假设您实际上在“某些代码”中的某处具有
await
关键字。 If not, then you should just remove async
. 如果没有,那么您应该删除
async
。
Or, you can simply use a #pragma
directive to suppress the warning: #pragma warning 或者,您可以简单地使用
#pragma
指令来禁止显示警告: #pragma warning
The solution that I used is to cheat compiler. 我使用的解决方案是欺骗编译器。
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 says that async code is unreachable heuristically, but compiler is satisfied. Visual Stuidio表示,异步代码无法启发式访问,但是编译器很满意。 Of course it is a little bit ugly, but it works.
当然,这有点难看,但是可以。 However thank you guys for trying to help)
但是谢谢你们的帮助)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.