HttpClient.SendAsync 坐下并且永远不会进展,即使发送的数据已被处理

Mat*_*ete 1 c# asp.net-mvc asynchronous async-await .net-4.6

我有从重写应用程序ASP.Net CoreASP.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)

Yuv*_*kov 6

我要在这里跛行,说你LogToBugZilla在调用堆栈的更高层使用这样的:

public void DoStuff()
{
    var result = LogToBugZilla("Component", exception).Result;
}
Run Code Online (Sandbox Code Playgroud)

这有效地使您的代码死锁,这也是您不应该阻塞异步代码的原因。你需要让你的代码“一直异步”,直到你的调用堆栈的顶部。这意味着转向DoStuffDoStuffAsync并调用它像这样:

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并返回 aTaskTask<T>