异步代码可能比同步花费更多时间吗?

时间:2018-05-17 06:51:01

标签: c# asynchronous task

我有一段代码可以从某个货币API执行HTTP请求(在循环内),并对收到的数据进行一些处理。

因为它很慢,我使用以下方法将其更改为异步函数:Task.Run()

然而,当我测量功能的计算时间(使用秒表..)时 使用异步方法,它比同步方法花费更多时间(甚至)。

怎么可能?我做错了吗?

[HttpPost,Route("GetCurrenciesData")]
public IHttpActionResult GetCurrenciesData(InputCurrenciesData cls)  
{
    try
    {
        var watch = Stopwatch.StartNew();

        var data2 = GetBL.mySyncMethod(cls.currenciesList);

        watch.Stop();
        string first = watch.Elapsed.ToString();  // --> this faster
        watch = Stopwatch.StartNew();
        var data = GetBL.myAsyncMethod(cls.currenciesList);
        string second = watch.Elapsed.ToString();  // --> this slower
        return Ok(data);
    }
    catch (Exception ex)
    {
        getGeneric.WriteError(ex.Message, ex.StackTrace);
        return BadRequest();
    }
}

同步功能的示例代码:

public GenericClass mySyncMethod(string[] currencies)
{
        try
        { 
            foreach (string currency in currencies)
            {

                getDataFromApi(currency);
            }


            return getDataChart;

        }
        catch (Exception ex)
        {
            WriteError(ex.Message, ex.StackTrace);
            return null;
        }
}

异步示例:

public GenericClass myAsyncMethod(string[] currencies)
    {
        try
        {
            List<Task> TaskList = new List<Task>();

            foreach (string currency in currenies)
            {

                var myTask = new Task(() =>
                {
                    getDataFromApi(currency);
                });
                myTask.Start();
                TaskList.Add(myTask);

            }

            Task.WaitAll(TaskList.ToArray());

            return getDataChart;

        }
        catch (Exception ex)
        {
            WriteError(ex.Message, ex.StackTrace);
            return null;
        }
    }

函数getDataFromApi的代码:

private void getDataFromApi(string currency)
    {

        string currencyCode = getCurrenciesDictionary[currency];

//Get api's URL from Web.config and concatenation the wanted currency code
        string URL = string.Format(GetConfig("Api"), currencyCode);  

        /*HTTP request to retrieve data from Api*/
        using (HttpClientHandler handler = new HttpClientHandler())
        {
            handler.UseDefaultCredentials = true;
            using (HttpClient httpClient = new HttpClient(handler))
            {
                var ResultAsync = httpClient.GetAsync(URL).Result;
                if (ResultAsync.IsSuccessStatusCode)
                {
                    var content = ResultAsync.Content;

                    string Data = content.ReadAsStringAsync().Result;

                    try
                    {
                        var ret = JsonConvert.DeserializeObject<RootObject>(Data);


                        /*add new class to currencyRate list - class which represent the currency and its rates*/
                        getDataChart.CurrencyRate.Add(new CurrencyRate
                        {
                            Currency = currency,
                            Rates = ret.dataset.data.AsEnumerable().
                                    Select(date => Double.Parse(date[1].ToString())).ToList()
                        });


                    }
                 catch (Exception ex)
                 {
                    WriteError(ex.Message + " currency: " + currency + "/n/ URL: " + URL, ex.StackTrace);
                }

             }
      }
}

1 个答案:

答案 0 :(得分:3)

试着读一下这个家伙:

他用几句话说出它是如何运作的。重点是使用async / await获得一些开销,但是,您可以释放资源。因此,任何将运行的任务都将在同步上下文中运行。但你可以处理更多的请求。

除了事实上你并没有真正使用异步功能 TO_DATE('20180924','yyyymmdd')+29 which returns the value as "23-OCT-18" 实际上杀死异步部分。

在短线中,做异步并不一定能加快速度。如果你有更多的CPU绑定任务,可以同时运行,你将获得主要的性能,但是,在你的情况下,你将无法表现,但像Kevin这样的资源在他的评论中说。

希望它有所帮助!