【发布时间】:2016-05-29 18:43:02
【问题描述】:
我有一段代码
var formContent =
new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("grant_type", "password"),
new KeyValuePair<string, string>("username", _userName),
new KeyValuePair<string, string>("password", _password)
});
var response = await InternalClient.PostAsync("/Token", formContent).ConfigureAwait(false);
当我在我的桌面应用程序中使用它时,它工作正常,但同样的部分在 Xamarin.Android 上失败了。我可以从模拟器浏览器访问我的网站,所以这不是没有这两者之间的连接的情况。更有趣的部分 - GetAsync 工作得非常好。由于超时,PostAsync 总是失败并出现 TaskCancelledException。所有 PostAsync 调用根本不会访问服务器。
我执行此操作的活动:
var isAuthSuccess = _mainClient.Authenticate();
isAuthSuccess.ContinueWith(task =>
{
RunOnUiThread(() =>
{
if (isAuthSuccess.Result)
{
ReleaseEventHandlers();
var nav = ServiceLocator.Current.GetInstance<INavigationService>();
nav.NavigateTo("MainChatWindow", _mainClient);
}
button.Enabled = true;
});
});
还有 Authenticate 方法:
public async Task<bool> Authenticate()
{
var getTokenOperation = new AsyncNetworkOperation<string>(GetTokenOperation);
var token = await getTokenOperation.Execute().ConfigureAwait(false);
if (getTokenOperation.IsCriticalFailure)
{
SetCriticalFailure(getTokenOperation.FailureReason);
}
if (getTokenOperation.IsFailure == false)
{
InternalClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
return true;
}
else
{
AuthenticationFailEncounteredEvent("Authentication fail encountered: " + getTokenOperation.FailureReason);
return false;
}
}
获取令牌操作:
private async Task<string> GetTokenOperation()
{
var formContent =
new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("grant_type", "password"),
new KeyValuePair<string, string>("username", _userName),
new KeyValuePair<string, string>("password", _password)
});
var response = await InternalClient.PostAsync("/Token", formContent).ConfigureAwait(false);
response.EnsureSuccessStatusCodeVerbose();
var responseJson = await response.Content.ReadAsStringAsync();
var jObject = JObject.Parse(responseJson);
var token = jObject.GetValue("access_token").ToString();
return token;
}
还有包装器 - AsyncNetworkOperation
public class AsyncNetworkOperation<T>
{
public bool IsFailure { get; set; }
public bool IsCriticalFailure { get; set; }
public string FailureReason { get; set; }
public bool IsRepeatable { get; set; }
public int RepeatsCount { get; set; }
public Func<Task<T>> Method { get; set; }
public AsyncNetworkOperation(Func<Task<T>> method, int repeatsCount)
{
Method = method;
IsRepeatable = true;
RepeatsCount = repeatsCount;
}
public AsyncNetworkOperation(Func<Task<T>> method)
{
Method = method;
}
public async Task<T> Execute()
{
try
{
return await Method().ConfigureAwait(false);
}
...exception handling logics
}
}
在活动中直接调用 PostAsync 的行为相同 - 等待很长时间,然后由于超时而失败并出现 TaskCancelledException。
【问题讨论】:
-
1) “失败”到底是什么意思? 2)这种方法的校准堆栈有什么不同吗?
-
失败是指它抛出异常并且从未真正命中服务器。没有检查调用堆栈差异 - 它只是在我用于桌面和 android 版本的同一个类库中。
-
添加了更多的源代码,现在图片更准确了
-
@HardLuck
InternalClient是否设置了超时或类似的东西?也许我会尝试删除所有.ConfigureAwait(false)代码,看看是否有什么不同。 -
不,它没有这样的设置,我试过删除 ConfigureAwait,同样的结果。强调两件事:它在 doktop 上运行良好,在 Xamarin 上从活动(而不是从库)调用 PostAsync 也失败了。 GetAsync 无处不在
标签: c# xamarin xamarin.android