Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
164 views
in Technique[技术] by (71.8m points)

c# - Make methods run asynchronously

Can someone please look at this code and tell me what I am doing wrong. It seems to me that this 3 methods should run in the same same, but they run each after another. Please take look at time writen on console. In my opinion all Console.WriteLine should show ~60ms. Code sample below:

private async void GetOneCombination(string firstMarket, string secondMarket, string thirdMarket, decimal amountOfFirstCurrency)
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();

        Task<GetMarketResponse> result = _accessMethods.GetOrderbook(firstMarket);
        Console.WriteLine(sw.ElapsedMilliseconds); // ~60ms
        Task<GetMarketResponse> result1 = _accessMethods.GetOrderbook(secondMarket);
        Console.WriteLine(sw.ElapsedMilliseconds); // ~130 ms
        Task<GetMarketResponse> result2 = _accessMethods.GetOrderbook(thirdMarket);
        Console.WriteLine(sw.ElapsedMilliseconds); // ~200 ms
        var getMarketResponses = await Task.WhenAll(result, result1, result2);

    }

Edit: To be hosnest I thought that it don`t matter whats inside this methods, i thought that no matter what is done inside it will be done 3 times at the same time

  public async Task<GetMarketResponse> GetOrderbook(string market = "USD")
    {
        var address = AddressBook._orderbook + market;
        var response = MethodExecutionTimeMeasurer.Invoke(() => 
            _client.ExecuteGetAsyncPublic<GetMarketResponse>(address), out timespan);
        _logger.LogInformation(string.Format("OrderBook requested for [{0}], response message: {1}. Time[ms]:{2}", 
            address, 
            response.Status,
            timespan));
        return response; 
    }

and ExecuteGetAsyncPublic:

   public async Task<T> ExecuteGetAsyncPublic<T>(string method)
        where T : IBasicResponse
    {
        var response = await _httpClient.GetAsync(method).ConfigureAwait(false);
        response.EnsureSuccessStatusCode();
        var json = await response.Content.ReadAsStringAsync();
        var responseData = JsonConvert.DeserializeObject<T>(json);
        return responseData;
    }

MethodExecutionTimeMeasurer

public static class MethodExecutionTimeMeasurer
{
    public static T Invoke<T>(Func<Task<T>> action, out TimeSpan timeSpan)
    {
        var timer = Stopwatch.StartNew();
        var res = action.Invoke();
        res.Wait();
        timer.Stop();
        timeSpan = timer.Elapsed;
        return res.Result;
    }

    public static void Invoke(Action action, out TimeSpan timeSpan)
    {
        var timer = Stopwatch.StartNew();
        action.Invoke();
        timer.Stop();
        timeSpan = timer.Elapsed;
    }
}
question from:https://stackoverflow.com/questions/65644103/make-methods-run-asynchronously

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There are two problems here:

  1. The GetOrderbook method has an asynchronous signature, but its implementation is synchronous. You are probably getting a warning for the async method lacking an await operator.

  2. The MethodExecutionTimeMeasurer.Invoke has a parameter Func<Task<T>> action (an asynchronous delegate), but the created Task is waited synchronously with the Wait method. So during the task's execution, the current thread is blocked.

Each of the three _accessMethods.GetOrderbook invocations returns a completed task, then the combined task Task.WhenAll(result, result1, result2) is also completed upon creation, and in short from the current thread's perspective nothing is running asynchronously. This case is very similar with a question that was asked yesterday, check it out.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...