[英]Page_Load is been fired when WebMethod is called through javascript PageMethods
[英]Async function deadlocks in WebMethod, but works fine if called in Page_Load
我有一個WebForms項目,試圖利用一些async
代碼。 在早期開發期間,我只是在Page_Load
(也是async
)中調用async
代碼,然后將結果寫入Response
。 易於測試。 一切都按預期進行。
該代碼可以總結為:
因此,當我嘗試在WebMethod
調用此async
方法而失敗時,我感到非常驚訝。 它似乎在其他async
代碼(特別是Azure AD AuthenticationContext.AcquireTokenAsync
方法)上陷入僵局。
我的第一個想法是一些上下文魔術,但是ConfigureAwait(false)
沒有任何作用。 因此,我對不同之處一無所知。 我嘗試過WebMethod
是否async
,結果沒有差異。 快速測試表明,此WebMethod
的配置沒有任何問題-讓我的代碼盡早返回(在到達AD代碼之前)可以按預期工作。 盡管那時沒有異步發生。
我還嘗試使用非異步方法來獲取Azure AD令牌。 這可以正常工作,但是當我的應用程序嘗試發出HTTP請求時(使用僅提供async
方法的RestSharp.Portable庫),它被卡住了。 我的代碼在那里:
protected async Task<JObject> PerformRequest(string path, Method method, string apiVersion, string requestBody)
{
RestClient client = new RestClient("https://management.azure.com");
RestRequest request = new RestRequest(path, method);
request.AddParameter("api-version", apiVersion);
request.AddHeader("Authorization", await this.GetAccessTokenAsync());
IRestResponse<JObject> response = await client.Execute<JObject>(request);
return response.Data;
}
我工作正常的Page_Load
和不工作的WebMethod
所使用的代碼實際上是相同的,只是WebMethod
返回結果,而Page_Load
將結果寫入Response
。
GetAccessToken
看起來像:
public async Task<string> GetAccessTokenAsync()
{
string tenantId = "xxx";
AuthenticationContext authenticationContext = new AuthenticationContext($"https://login.windows.net/{tenantId}");
ClientCredential credential = new ClientCredential(clientId: "xxx", clientSecret: "xxx=");
AuthenticationResult result = await authenticationContext.AcquireTokenAsync(resource: "https://management.core.windows.net/", clientCredential: credential);
if (result == null) throw new InvalidOperationException("Failed to obtain the JWT token");
return this.accessToken = result.AccessTokenType + " " + result.AccessToken;
}
所有這些調用都直接在WebMethod
(這是WebMethod
當前唯一要做的事情):
return await this.PerformRequest("xxx", Method.GET, "xxx", null).ContinueWith(result => result.ToString());
為什么我的應用程序在WebMethod
中而不是Page_Load
調用此代碼時可能會遇到此問題? 我該如何解決該問題?
改變你的
IRestResponse<JObject> response = await client.Execute<JObject>(request);
至
IRestResponse<JObject> response = await client.Execute<JObject>(request).ConfigureAwait(false);
這對您有幫助嗎? 問題是兩個“ await”都在等待同時捕獲同一上下文,ConfigureWait阻止了此操作(請閱讀其文檔)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.