繁体   English   中英

我如何加快此C#HttpWebRequest的速度?

[英]How can I speed up this c# HttpWebRequest?

我在SSIS作业中有一个ac#脚本任务,该调用为地理编码的目的而调用API。 该API是专有的,可以像这样进行工作,接收请求,获取地址字符串,然后尝试将字符串与庞大的地址列表(百万)进行匹配,如果找不到,则转到其他服务(例如Google)并获取地理数据信息。

可以想象,每个请求的字符串匹配都占用大量时间。 有时,每分钟只有一个请求那么慢,而我有4M地址需要这样做。 不能在API方面进行任何开发工作。 为了更好地了解此过程,这是我目前正在做的事情:

我从数据库中提取了一个地址列表(大约4M),并将其放在数据表中并设置了变量:

        // Fill c# datatable with query results
        sdagetGeoData.Fill(dtGeoData);

        // check to ensure datable has rows
        if (dtGeoData.Rows.Count > 0)
        { 
            // if datatable has rows, for every row set the varible
            foreach (System.Data.DataRow row in dtGeoData.Rows)
            {
                localID = row[0].ToString();
                address = row[1].ToString();
                city    = row[2].ToString();
                state   = row[3].ToString();
                zip     = row[4].ToString();
                country = row[5].ToString();

                // after varaibles are set, now run this method to post, get response and insert the string
                GetGLFromAddress();
            }
        }

GetGLFromAddress()工作方式如下:

从上面获取变量并形成JSON。 使用“ POST ”和httpWebRequest发送JSON。 等待请求(耗时)。 退货要求。 用返回值设置新变量。 使用这些变量来更新/插入数据库,然后遍历原始数据表的下一行。

理解此流程很重要,因为我需要能够随每个请求保留localID变量,以便可以更新数据库中的正确记录。

这是GetGLFromAddress()

    private void GetGLFromAddress()
    {
        // Request JSON data with Payload
        var httpWebRequest = (HttpWebRequest)WebRequest.Create("http:");
        httpWebRequest.Headers.Add("Authorization", "");
        httpWebRequest.ContentType = "application/json";
        httpWebRequest.Method = "POST";

        using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
        {
            // this takes the variables from your c# datatable and formats them for json post
            var jS = new JavaScriptSerializer();
            var newJson = jS.Serialize(new SeriesPost()
            {
                AddressLine1 = address,
                City         = city,
                StateCode    = state,
                CountryCode  = country,
                PostalCode   = zip,
                CreateSiteIfNotFound = true
            });


            //// So you can see the JSON thats output
            System.Diagnostics.Debug.WriteLine(newJson);
            streamWriter.Write(newJson);
            streamWriter.Flush();
            streamWriter.Close();

        }

        try
        {
            var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
            using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
            {
                var result = streamReader.ReadToEnd();
                // javascript serializer... deserializing the returned json so that way you can set the variables used for insert string
                var p1 = new JavaScriptSerializer();

                // after this line, obj is a fully deserialzed string of json  Notice how I reference obj[x].fieldnames below.  If you ever want to change the fiels or bring more in
                // this is how you do it.
                var obj = p1.Deserialize<List<RootObject>>(result);

                // you must ensure the values returned are not null before trying to set the variable.  You can see when that happens, I'm manually setting the variable value to null.
                if (string.IsNullOrWhiteSpace(obj[0].MasterSiteId))
                {
                    retGLMID = "null";
                }
                else
                {
                    retGLMID = obj[0].MasterSiteId.ToString();
                }

                if (string.IsNullOrWhiteSpace(obj[0].PrecisionName))
                {
                    retAcc = "null";
                }
                else
                {
                    retAcc = obj[0].PrecisionName.ToString();
                }

                if (string.IsNullOrWhiteSpace(obj[0].PrimaryAddress.AddressLine1Combined))
                {
                    retAddress = "null";
                }
                else
                {
                    retAddress = obj[0].PrimaryAddress.AddressLine1Combined.ToString();
                }

                if (string.IsNullOrWhiteSpace(obj[0].Latitude))
                {
                    retLat = "null";
                }
                else
                {
                    retLat = obj[0].Latitude.ToString();
                }

                if (string.IsNullOrWhiteSpace(obj[0].Longitude))
                {
                    retLong = "null";
                }
                else
                {
                    retLong = obj[0].Longitude.ToString();
                }
                retNewRecord = obj[0].IsNewRecord.ToString();

                // Build insert string... notice how I use the recently created variables
                // string insertStr = retGLMID + ", '" + retAcc + "', '" + retAddress + "', '" + retLat + "', '" + retLong + "', '" + localID;
                string insertStr = "insert into table        " +
                                   "(ID,GLM_ID,NEW_RECORD_IND,ACCURACY)    " +
                                   " VALUES                                       " +
                                   "('" + localID + "', '" + retGLMID + "', '" + retNewRecord + "', '" + retAcc + "')"; 


                string connectionString = "Data Source=; Initial Catalog=; Trusted_Connection=Yes";
                using (SqlConnection connection = new SqlConnection(connectionString))
                {
                    SqlCommand cmd  = new SqlCommand(insertStr);
                    cmd.CommandText = insertStr;
                    cmd.CommandType = CommandType.Text;
                    cmd.Connection  = connection;
                    connection.Open();
                    cmd.ExecuteNonQuery();
                    connection.Close();
                }
            }
        }

        {
            string insertStr2  = "insert into table  " +
                               "(ID,GLM_ID,NEW_RECORD_IND,ACCURACY)    " +
                               " VALUES                                       " +
                               "('" + localID + "', null, null, 'Not_Found')";
            string connectionString2 = "Data Source=; Initial Catalog=; Trusted_Connection=Yes";

            using (SqlConnection connection = new SqlConnection(connectionString2))
            {
                SqlCommand cmd  = new SqlCommand(insertStr2);
                cmd.CommandText = insertStr2;
                cmd.CommandType = CommandType.Text;
                cmd.Connection  = connection;
                connection.Open();
                cmd.ExecuteNonQuery();
                connection.Close();
            }
        }
    }

当我尝试使用Parallel.Foreach ,我遇到了变量问题。 我想运行多个请求,但是如果有意义的话,请为每个请求保留变量的每个实例。 我没有办法将localID传递给API并返回它,否则那将是理想的选择。

这有可能吗?

我将如何构造此调用以实现自己的目标?

本质上,我希望能够发送多个呼叫,以加快整个过程。

编辑:添加了GetGlFromAddress()的代码。 是的,我是新手,所以请客气:)

将所有数据放入一个数组中,一次可以调用多个请求,最好使用多任务或异步方法来调用API。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM