我不得不重写从ASP.Net Core
到ASP.Net 4.6.1
的应用程序,在应用程序的核心版本中,我将Json
数据发送到BugZilla进行处理,它运行正常。它发送数据并相当快地获得响应。 4.6.1版本的应用程序中的相同代码位于send命令上并挂起。我可以进入BugZilla并看到它获取数据并生成错误,但即使在15分钟后应用程序也无法进展。我是Task的新手,并通过Json发送数据,所以我不知道为什么我遇到这个问题。没有错误返回,在调试模式下,我可以逐步完成所有操作,并知道它正在SendAsync
行处理并等待。我在4.6.1中打破这个错误做错了什么?
private static async Task<int> LogToBugZilla(string Component, Exception ex)
{
var ErrorSummary = "Auto Error Logging: " + ex.Message + " " + ex.InnerException.Message;
var BugData = new Dictionary<string, string>
{
{ "Bugzilla_api_key", ConfigurationManager.AppSettings["BugZillaAPIKey"] },
{ "product", "Job Site" },
{ "component", Component },
{ "version", ConfigurationManager.AppSettings["AppVersion"] },
{ "summary", ErrorSummary },
{ "op_sys", "All" },
{ "platform", "Other" },
{ "description", ex.StackTrace + ex.InnerException.StackTrace }
};
string Json = JsonConvert.SerializeObject(BugData, Formatting.None);
var Client = new HttpClient();
var Request = new HttpRequestMessage(HttpMethod.Post, "http://bugzilla/rest/bug");
Request.Content = new StringContent(Json, Encoding.UTF8, "application/json");
Request.Headers.Add("Accept", "application/json");
var Response = await Client.SendAsync(Request);
var JsonResults = await Response.Content.ReadAsStringAsync();
if (Response.StatusCode == HttpStatusCode.OK)
{
var Results = JsonConvert.DeserializeObject<Dictionary<string, int>>(JsonResults);
return Results["id"];
}
else
{
return -1;
}
}
编辑:
public static string ProcessError(Exception ex, string OriginatingController)
{
var Component = GetComponent(OriginatingController);
string UserErrorMessage = "";
switch (ex.GetType().ToString())
{
case "System.Data.DataException":
LogToITSupport("Database Connection");
UserErrorMessage = @"An error has accrued connecting to the database. <a href=""mailto:"">IT Support</a> has been notified of this error. Please try your request again later, thank you.";
break;
default:
var BugID = LogToBugZilla(Component, ex).Result;
UserErrorMessage = @"An error has accrued processing your request and a log of this error has been made on the <a href=""http://bugzilla/show_bug.cgi?id=" + BugID + "\">Internal Tools BugZilla system</a> with an ID of " + BugID + ". Please try your request again later, thank you.";
break;
}
return UserErrorMessage;
}
要重申,应用程序会挂起代码var Response = await Client.SendAsync(Request);
编辑2:
Contrller代码:
public ActionResult About()
{
try
{
using (var db = new JobSightDbContext())
{
var model = db.ReleaseVersions
.OrderByDescending(rv => rv.DateReleased)
.Select(rv => new ReleaseNotesVM()
{
ID = rv.ID,
CurrentVersion = string.Concat(rv.Major, ".", rv.Minor, ".", rv.Patch),
CurrentVersionReleaseDate = rv.DateReleased,
ReleaseNotes = rv.ReleaseNotes.Select(rn => rn.Note).ToList()
}).First();
//model.VersionList = db.ReleaseVersions
// .OrderByDescending(rv => rv.DateReleased)
// .Select(rv => new SelectListItem()
// {
// Value = rv.ID.ToString(),
// Text = string.Concat(rv.Major, '.', rv.Minor, '.', rv.Patch)
// }).ToList();
return View(model);
}
}
catch (System.Data.DataException ex)
{
ViewBag.ErrorMessage = EHALM.ProcessError(ex, RouteData.Values["controller"].ToString());
return View("Dashboard");
}
}
答案 0 :(得分:4)
我会在这里跛行,并说你在你的调用堆栈中使用LogToBugZilla
更高的位置:
public void DoStuff()
{
var result = LogToBugZilla("Component", exception).Result;
}
这实际上使代码陷入僵局,这就是you shouldn't block on async code的原因。您需要将代码&#34; async一直保持为#34;,直到调用堆栈的顶部。这意味着将DoStuff
转为DoStuffAsync
并将其称为:
public async Task DoStuffAsync()
{
var result = await LogToBugZillaAsync("Component", exception);
// Do stuff with result
}
注意我添加了&#34; async&#34;根据推荐的编码约定,后缀为LogToBugZilla
。
修改强>
鉴于您提供了调用方法,它应如下所示:
public static async Task<string> ProcessErrorAsync(
Exception ex, string OriginatingController)
{
var Component = GetComponent(OriginatingController);
string UserErrorMessage = "";
switch (ex.GetType().ToString())
{
case "System.Data.DataException":
LogToITSupport("Database Connection");
UserErrorMessage = @"An error has accrued connecting to the
database. <a href=""mailto:"">IT Support</a> has been notified
of this error. Please try your request again later, thank you.";
break;
default:
var bugId = await LogToBugZillaAsync(Component, ex);
UserErrorMessage = @"An error has accrued processing your request
and a log of this error has been made
on the <a href=""http://bugzilla/show_bug.cgi?id=" + BugID +
"\">Internal Tools BugZilla system</a>
with an ID of " + bugId + ". Please try your request again later, thank you.";
break;
}
return UserErrorMessage;
}
现在请记住,这需要一路向上。这意味着调用ProcessErrorAsync
的每个方法本身都应该async
并返回Task
或Task<T>
。
答案 1 :(得分:1)
这是我用来发送HTTP请求的一些通用代码。工作正常只有差异是我使用.Net 4.5。应该不是4.6的问题
private async Task<HttpUtilResponse> DoRequest(List<RequestResponseHeader> headers, HttpMethod method, string url, string requestData) {
HttpUtilResponse response = new HttpUtilResponse();
string responseData = string.Empty;
using (System.Net.Http.HttpClient client = new System.Net.Http.HttpClient()) {
using (HttpRequestMessage request = new HttpRequestMessage(method, url)) {
if (headers != null) {
headers.ForEach(h => request.Headers.Add(h.Name, h.Value));
}
if (!string.IsNullOrEmpty(requestData)) {
if (AppConfig.LogRequestContent) {
LOG.Debug(requestData);
}
request.Content = new StringContent(requestData, Encoding.UTF8, JSON_CONTENT);
}
using (HttpResponseMessage msg = await client.SendAsync(request, CancelToken.Token)) {
response.StatusCode = msg.StatusCode;
response.ReasonPhrase = msg.ReasonPhrase;
using (HttpContent content = msg.Content) {
response.ResponseText = await content.ReadAsStringAsync();
}
}
}
}
return response;
}