2

我试图了解如何从 jquery 1.9.1 调用使用 async/await 的 .net 4.5 Web 服务(asmx)。js代码很经典:

$.ajax({
    type: "POST",
    url: "ws/UpdCategory",
    data: strData,
    async: true,
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    complete: saveCategory_onComplete
});

ws.cs 中的 web 服务,ws.asmx 后面的代码:

[WebMethod]
public async Task<int> UpdCategory(string jsonData)
{
    JsonGenericResponse objWmJson = new JsonGenericResponse();
    objWmJson.IsInError = "true";
    try
    {
        JavaScriptSerializer objJss = new JavaScriptSerializer();
        Dictionary<string, string> objDict = objJss.Deserialize<Dictionary<string, string>>(jsonData);
        DataIfCloudEspresso objData = new DataIfCloudEspresso();
        //
        StringBuilder objBuilder = new StringBuilder();
        objBuilder.Append("<?xml version=" + (char)39 + "1.0" + (char)39 + " encoding=" + (char)39 + ConfigurationService.XMLEncoding + (char)39 + "?>");
        objBuilder.Append("<Category>");
        .....various fields
        objBuilder.Append("</Category>");
        // the row below call the method on Data Access Layer
        int updatedCount = await objData.UpdCategory(objBuilder.ToString());
        return updatedCount;
    }
}

最后是 DAL 方法:

public async Task<int> UpdCategorieArticoli(string xmlData)
{
    try
    {
        using (SqlConnection objConn = new SqlConnection(base.ConnectionString))
        {
            using (SqlCommand cmdADO = new SqlCommand("spUpd_Category", objConn))
            {
                cmdADO.Parameters.Add(new System.Data.SqlClient.SqlParameter("@XMLDoc", SqlDbType.Text));
                cmdADO.Parameters["@XMLDoc"].Value = xmlData;
                cmdADO.Parameters.Add(new System.Data.SqlClient.SqlParameter("@RETURN_VALUE", SqlDbType.Int));
                cmdADO.Parameters["@RETURN_VALUE"].Direction = ParameterDirection.ReturnValue;
                //
                cmdADO.CommandType = CommandType.StoredProcedure;
                //
                await objConn.OpenAsync().ConfigureAwait(false);
                return await cmdADO.ExecuteNonQueryAsync().ConfigureAwait(false);
            }
        }
    }
    catch (Exception)
    {
        throw;
    }
    finally
    {
    }
}

问题是这样的:例如,如果从 Page_Load 调用 DAL 方法,则可以正常工作;相反,当从 Web 服务(从 javascript 调用)调用时,代码挂在等待 cmdADO.ExecuteNonQueryAsync() 的行上。

我想问题是来自客户端的上下文切换(来自浏览器的 js 代码)和背后的代码在服务器上运行,我不明白如何解决这个问题。我尝试了各种在谷歌上搜索的代码,但没有解决方案。

显而易见的范围是最大限度地使用异步代码以获得最大性能。

我尝试编写带有回调的旧样式 BeginExecuteNonQuery,但我还没有找到解决方案,说明如何将结果从 EndExecuteNonQuery 传递给调用 Web 服务。

4

2 回答 2

2

根据Is it possible to use async/await in webmethod asmx service 的评论,ASMX 根本不支持async。这就是你的代码不起作用的原因。它也与 jQuery 异步无关。

于 2013-03-11T01:16:42.660 回答
1

jQuery 异步本身就是一个异步。这就是正在发生的事情。当您调用 Web 服务时,它会异步执行数据访问逻辑并向 Web 服务返回 http 响应 OK,这意味着该方法已成功执行,但没有返回任何结果。

当您从 Page_Load 调用它时,这意味着页面的渲染将为所有异步方法完成以执行渲染。

所以底线是不要在 Web 服务上使用异步,因为你在 jQuery 端有异步。

于 2013-03-11T00:51:26.917 回答