Mat*_*ete 1 c# asp.net-mvc asynchronous async-await .net-4.6
我有从重写应用程序ASP.Net Core来ASP.Net 4.6.1和我送的应用程序的核心版本Json数据Bugzilla的处理,它工作正常。它发送数据并很快得到响应。应用程序 4.6.1 版本中的相同代码位于并挂起发送命令。我可以进入 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;
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:
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;
}
Run Code Online (Sandbox Code Playgroud)
重申一下,应用程序挂在代码上 var Response = await Client.SendAsync(Request);
编辑2:
控制器代码:
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");
}
}
Run Code Online (Sandbox Code Playgroud)
我要在这里跛行,说你LogToBugZilla在调用堆栈的更高层使用这样的:
public void DoStuff()
{
var result = LogToBugZilla("Component", exception).Result;
}
Run Code Online (Sandbox Code Playgroud)
这有效地使您的代码死锁,这也是您不应该阻塞异步代码的原因。你需要让你的代码“一直异步”,直到你的调用堆栈的顶部。这意味着转向DoStuff到DoStuffAsync并调用它像这样:
public async Task DoStuffAsync()
{
var result = await LogToBugZillaAsync("Component", exception);
// Do stuff with result
}
Run Code Online (Sandbox Code Playgroud)
请注意,我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;
}
Run Code Online (Sandbox Code Playgroud)
现在记住这需要一直向上。这意味着每个方法调用ProcessErrorAsync本身都应该被调用async并返回 aTask或Task<T>。