使用 HttpWebResponse 时 Xamarin Android 中未处理的异常
Unhandled Exception in Xamarin Android When Using HttpWebResponse
我有以下代码:
public async Task<List<RobotViewModel>> GetBot(string token)
{
var menulist = new List<RobotViewModel>();
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("mysite/bot/abc/process/GetBot");
request.Accept = "application/json";
request.Method = "GET";
request.Headers["Authorization"] = "Bearer " + token;
var response = (HttpWebResponse)await request.GetResponseAsync().ConfigureAwait(false);
if(response.StatusCode==HttpStatusCode.OK)
{
var encoding = ASCIIEncoding.UTF8;
using (var reader = new System.IO.StreamReader(response.GetResponseStream(), encoding))
{
string responseText = reader.ReadToEnd();
menulist = JsonConvert.DeserializeObject<List<RobotViewModel>>(responseText);
}
}
}
catch(System.Net.WebException exc)
{
var response = (HttpWebResponse)exc.Response;
switch(response.StatusCode)
{
case HttpStatusCode.InternalServerError:
{
_userRepo = await new Repository<User>().MakeDatabaseAsync();
var user = await _userRepo.Table.Where(p => p.LoggedIn).FirstOrDefaultAsync();
await Login(user.UserName, user.Password);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("mysite/bot/abc/process/GetBot");
request.Accept = "application/json";
request.Method = "GET";
request.Headers["Authorization"] = "Bearer " + user.AccessToken;
response = (HttpWebResponse)await request.GetResponseAsync().ConfigureAwait(false);
if (response.StatusCode == HttpStatusCode.OK)
{
var encoding = ASCIIEncoding.UTF8;
using (var reader = new System.IO.StreamReader(response.GetResponseStream(), encoding))
{
string responseText = reader.ReadToEnd();
menulist = JsonConvert.DeserializeObject<List<RobotViewModel>>(responseText);
}
}
break;
}
default:
throw;
}
}
catch(Exception exc)
{
}
return menulist;
}
此代码用于以下委托:
navigationView.NavigationItemSelected += async delegate
{
AndHUD.Shared.Show(this, "Please Wait", -1, AndroidHUD.MaskType.Clear);
var botList = await client.GetBot(loggedInUser.AccessToken);
if (botList.Count > 0)
{
var botListMemory = await _botRepo.GetAllAsync();
foreach (var item in botList)
{
var bot =await _botRepo.Table.Where(p => p.Token == item.Token).FirstOrDefaultAsync();
if(bot==null)
await _botRepo.CreateAsync(new Robot
{
Name = item.Name,
Token = item.Token,
TokenUrl = item.TokenUrl,
UserId = loggedInUser.Id,
Description = item.Description
});
else
{
bot.Name = item.Name;
bot.Token = item.Token;
bot.TokenUrl = item.TokenUrl;
bot.UserId = loggedInUser.Id;
bot.Description = item.Description;
await _botRepo.UpdateAsync(bot);
}
}
AndHUD.Shared.ShowSuccess(this, "Success", MaskType.Clear, TimeSpan.FromSeconds(2));
}
else
AndHUD.Shared.ShowError(this, "Server Error", MaskType.Clear, TimeSpan.FromSeconds(2));
SetData(botList, out myAdapter);
expandableListView.SetAdapter(myAdapter);
};
当 Bearer 令牌过期时,catch 块会引发未处理的异常。当我重新运行 程序时,一切正常,因为新的 Bearer 令牌已在先前应用程序 运行.
的 catch 块中生成
代码中有很多问题:
- ConfigureAwait(false) 应该只在 class 库中使用,因为它会导致当前任务由 threadPool 中的线程处理,而不是主线程...
httpClient 应该在 using 块中将其从 using 块中释放出来。
所以我改变了 GetBot 方法如下:
public async Task<List<RobotViewModel>> GetBot(string token)
{
var menulist = new List<RobotViewModel>();
using (var localClient = new HttpClient())
{
try
{
localClient.MaxResponseContentBufferSize = 256000;
localClient.Timeout = TimeSpan.FromSeconds(40);
localClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
localClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var uri = new Uri("mySite/GetBot");
var response = await localClient.GetAsync(uri);
if (response.StatusCode == HttpStatusCode.OK)
{
var encoding = ASCIIEncoding.UTF8;
using (var reader = new System.IO.StreamReader(await response.Content.ReadAsStreamAsync(), encoding))
{
string responseText = reader.ReadToEnd();
menulist = JsonConvert.DeserializeObject<List<RobotViewModel>>(responseText);
}
}
}
catch (Exception ex)
{
throw ex;
}
}
return menulist;
}
然后在异步委托中使用它:
navigationView.NavigationItemSelected += async delegate
{
AndHUD.Shared.Show(this, "Please Wait", -1, AndroidHUD.MaskType.Clear);
var botList = new List<RobotViewModel>();
var cts = new CancellationTokenSource();
try
{
_userRepo = await new Repository<User>().MakeDatabaseAsync();
var user = await _userRepo.Table.Where(p => p.LoggedIn).FirstOrDefaultAsync();
botList = await client.GetBot(user.AccessToken);
if (botList.Count > 0)
{
foreach (var item in botList)
{
var bot = await _botRepo.Table.Where(p => p.Token == item.Token).FirstOrDefaultAsync();
if (bot == null)
await _botRepo.CreateAsync(new Robot
{
Name = item.Name,
Token = item.Token,
TokenUrl = item.TokenUrl,
UserId = loggedInUser.Id,
Description = item.Description
});
else
{
bot.Name = item.Name;
bot.Token = item.Token;
bot.TokenUrl = item.TokenUrl;
bot.UserId = loggedInUser.Id;
bot.Description = item.Description;
await _botRepo.UpdateAsync(bot);
}
}
SetData(botList, out myAdapter);
expandableListView.SetAdapter(myAdapter);
AndHUD.Shared.ShowSuccess(this, "Success", MaskType.Clear, TimeSpan.FromSeconds(2));
}
else
{
_userRepo = await new Repository<User>().MakeDatabaseAsync();
user = await _userRepo.Table.Where(p => p.LoggedIn).FirstOrDefaultAsync();
var loginResponse = await client.Login(user.UserName, user.Password);
botList = await client.GetBot(loginResponse.access_token);
if (botList.Count > 0)
{
foreach (var item in botList)
{
var bot = await _botRepo.Table.Where(p => p.Token == item.Token).FirstOrDefaultAsync();
if (bot == null)
await _botRepo.CreateAsync(new Robot
{
Name = item.Name,
Token = item.Token,
TokenUrl = item.TokenUrl,
UserId = loggedInUser.Id,
Description = item.Description
});
else
{
bot.Name = item.Name;
bot.Token = item.Token;
bot.TokenUrl = item.TokenUrl;
bot.UserId = loggedInUser.Id;
bot.Description = item.Description;
await _botRepo.UpdateAsync(bot);
}
}
SetData(botList, out myAdapter);
expandableListView.SetAdapter(myAdapter);
AndHUD.Shared.ShowSuccess(this, "Success", MaskType.Clear, TimeSpan.FromSeconds(2));
}
}
}
catch (Exception ex)
{
if (ex is AggregateException)
{
AndHUD.Shared.ShowError(this, "IO Error", MaskType.Clear, TimeSpan.FromSeconds(2));
}
else
AndHUD.Shared.ShowError(this, "Unknown", MaskType.Clear, TimeSpan.FromSeconds(2));
}
};
现在一切正常!感谢您的宝贵时间!
我有以下代码:
public async Task<List<RobotViewModel>> GetBot(string token)
{
var menulist = new List<RobotViewModel>();
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("mysite/bot/abc/process/GetBot");
request.Accept = "application/json";
request.Method = "GET";
request.Headers["Authorization"] = "Bearer " + token;
var response = (HttpWebResponse)await request.GetResponseAsync().ConfigureAwait(false);
if(response.StatusCode==HttpStatusCode.OK)
{
var encoding = ASCIIEncoding.UTF8;
using (var reader = new System.IO.StreamReader(response.GetResponseStream(), encoding))
{
string responseText = reader.ReadToEnd();
menulist = JsonConvert.DeserializeObject<List<RobotViewModel>>(responseText);
}
}
}
catch(System.Net.WebException exc)
{
var response = (HttpWebResponse)exc.Response;
switch(response.StatusCode)
{
case HttpStatusCode.InternalServerError:
{
_userRepo = await new Repository<User>().MakeDatabaseAsync();
var user = await _userRepo.Table.Where(p => p.LoggedIn).FirstOrDefaultAsync();
await Login(user.UserName, user.Password);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("mysite/bot/abc/process/GetBot");
request.Accept = "application/json";
request.Method = "GET";
request.Headers["Authorization"] = "Bearer " + user.AccessToken;
response = (HttpWebResponse)await request.GetResponseAsync().ConfigureAwait(false);
if (response.StatusCode == HttpStatusCode.OK)
{
var encoding = ASCIIEncoding.UTF8;
using (var reader = new System.IO.StreamReader(response.GetResponseStream(), encoding))
{
string responseText = reader.ReadToEnd();
menulist = JsonConvert.DeserializeObject<List<RobotViewModel>>(responseText);
}
}
break;
}
default:
throw;
}
}
catch(Exception exc)
{
}
return menulist;
}
此代码用于以下委托:
navigationView.NavigationItemSelected += async delegate
{
AndHUD.Shared.Show(this, "Please Wait", -1, AndroidHUD.MaskType.Clear);
var botList = await client.GetBot(loggedInUser.AccessToken);
if (botList.Count > 0)
{
var botListMemory = await _botRepo.GetAllAsync();
foreach (var item in botList)
{
var bot =await _botRepo.Table.Where(p => p.Token == item.Token).FirstOrDefaultAsync();
if(bot==null)
await _botRepo.CreateAsync(new Robot
{
Name = item.Name,
Token = item.Token,
TokenUrl = item.TokenUrl,
UserId = loggedInUser.Id,
Description = item.Description
});
else
{
bot.Name = item.Name;
bot.Token = item.Token;
bot.TokenUrl = item.TokenUrl;
bot.UserId = loggedInUser.Id;
bot.Description = item.Description;
await _botRepo.UpdateAsync(bot);
}
}
AndHUD.Shared.ShowSuccess(this, "Success", MaskType.Clear, TimeSpan.FromSeconds(2));
}
else
AndHUD.Shared.ShowError(this, "Server Error", MaskType.Clear, TimeSpan.FromSeconds(2));
SetData(botList, out myAdapter);
expandableListView.SetAdapter(myAdapter);
};
当 Bearer 令牌过期时,catch 块会引发未处理的异常。当我重新运行 程序时,一切正常,因为新的 Bearer 令牌已在先前应用程序 运行.
的 catch 块中生成代码中有很多问题:
- ConfigureAwait(false) 应该只在 class 库中使用,因为它会导致当前任务由 threadPool 中的线程处理,而不是主线程...
httpClient 应该在 using 块中将其从 using 块中释放出来。 所以我改变了 GetBot 方法如下:
public async Task<List<RobotViewModel>> GetBot(string token) { var menulist = new List<RobotViewModel>(); using (var localClient = new HttpClient()) { try { localClient.MaxResponseContentBufferSize = 256000; localClient.Timeout = TimeSpan.FromSeconds(40); localClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); localClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); var uri = new Uri("mySite/GetBot"); var response = await localClient.GetAsync(uri); if (response.StatusCode == HttpStatusCode.OK) { var encoding = ASCIIEncoding.UTF8; using (var reader = new System.IO.StreamReader(await response.Content.ReadAsStreamAsync(), encoding)) { string responseText = reader.ReadToEnd(); menulist = JsonConvert.DeserializeObject<List<RobotViewModel>>(responseText); } } } catch (Exception ex) { throw ex; } } return menulist; }
然后在异步委托中使用它:
navigationView.NavigationItemSelected += async delegate { AndHUD.Shared.Show(this, "Please Wait", -1, AndroidHUD.MaskType.Clear); var botList = new List<RobotViewModel>(); var cts = new CancellationTokenSource(); try { _userRepo = await new Repository<User>().MakeDatabaseAsync(); var user = await _userRepo.Table.Where(p => p.LoggedIn).FirstOrDefaultAsync(); botList = await client.GetBot(user.AccessToken); if (botList.Count > 0) { foreach (var item in botList) { var bot = await _botRepo.Table.Where(p => p.Token == item.Token).FirstOrDefaultAsync(); if (bot == null) await _botRepo.CreateAsync(new Robot { Name = item.Name, Token = item.Token, TokenUrl = item.TokenUrl, UserId = loggedInUser.Id, Description = item.Description }); else { bot.Name = item.Name; bot.Token = item.Token; bot.TokenUrl = item.TokenUrl; bot.UserId = loggedInUser.Id; bot.Description = item.Description; await _botRepo.UpdateAsync(bot); } } SetData(botList, out myAdapter); expandableListView.SetAdapter(myAdapter); AndHUD.Shared.ShowSuccess(this, "Success", MaskType.Clear, TimeSpan.FromSeconds(2)); } else { _userRepo = await new Repository<User>().MakeDatabaseAsync(); user = await _userRepo.Table.Where(p => p.LoggedIn).FirstOrDefaultAsync(); var loginResponse = await client.Login(user.UserName, user.Password); botList = await client.GetBot(loginResponse.access_token); if (botList.Count > 0) { foreach (var item in botList) { var bot = await _botRepo.Table.Where(p => p.Token == item.Token).FirstOrDefaultAsync(); if (bot == null) await _botRepo.CreateAsync(new Robot { Name = item.Name, Token = item.Token, TokenUrl = item.TokenUrl, UserId = loggedInUser.Id, Description = item.Description }); else { bot.Name = item.Name; bot.Token = item.Token; bot.TokenUrl = item.TokenUrl; bot.UserId = loggedInUser.Id; bot.Description = item.Description; await _botRepo.UpdateAsync(bot); } } SetData(botList, out myAdapter); expandableListView.SetAdapter(myAdapter); AndHUD.Shared.ShowSuccess(this, "Success", MaskType.Clear, TimeSpan.FromSeconds(2)); } } } catch (Exception ex) { if (ex is AggregateException) { AndHUD.Shared.ShowError(this, "IO Error", MaskType.Clear, TimeSpan.FromSeconds(2)); } else AndHUD.Shared.ShowError(this, "Unknown", MaskType.Clear, TimeSpan.FromSeconds(2)); } };
现在一切正常!感谢您的宝贵时间!