简体   繁体   English

使用预处理器指令在异步方法中引发异常

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM