2016-06-22 28 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

但是第一部分是錯誤的(或不完整),因爲正如問題中提到的那樣,他已經嘗試過了,它給出了不同的警告。 –

相關問題