简体   繁体   中英

How to parallelize this code using async await

I am trying to understand async programming better. I wrote this code and added async but the speed is still the same. Each subscription call takes more than a second so when I print it in the console, it's still working synchronously.

All I want is to perform each subscribe call asynchronously. Also because the first function has many subscribe calls, I am not sure whether that should be async or whether I should async the second call. Because at the start of the program, I have to call the first function like 50 times. Later on I only call the first function 1 time when a new item is added.

public static List<Task<CallResult<UpdateSubscription>>> AddNewSubscription(
    BinanceSocketClient socketClient, Coin coin)
{
    List<Task<CallResult<UpdateSubscription>>> tasks =
        new List<Task<CallResult<UpdateSubscription>>>();
    List<UpdateSubscription> subs = new List<UpdateSubscription>();

    var sub = socketClient.Spot.SubscribeToSymbolTickerUpdatesAsync(coin.SymbolPair,
        data =>
    {
        coin.Price = data.LastPrice;
        coin.LowestDailyPrice = data.LowPrice;
        coin.HighestDailyPrice = data.HighPrice;
        coin.PriceChangeInPercentDaily = data.PriceChangePercent;
    });
    tasks.Add(sub);
    subs.Add(sub.Result.Data);

    sub = socketClient.Spot.SubscribeToKlineUpdatesAsync(coin.SymbolPair,
        KlineInterval.OneHour, data =>
    {
        coin.LastHourOpenPrice = data.Data.Open;
        coin.LastHourVolume = data.Data.BaseVolume;
        coin.TotalBuyVolume = data.Data.TakerBuyBaseVolume;
        coin.TotalSellVolume = coin.LastHourVolume - coin.TotalBuyVolume;
    });
    tasks.Add(sub);
    subs.Add(sub.Result.Data);

    sub = socketClient.Spot.SubscribeToKlineUpdatesAsync(coin.SymbolPair,
        KlineInterval.OneMinute, data =>
    {
        coin.LastMinuteOpenPrice = data.Data.Open;
    });
    tasks.Add(sub);
    subs.Add(sub.Result.Data);

    Utility.ActiveSubscriptions.Add(coin.Symbol, subs);

    return tasks;
}

public static async Task AddNewSubscriptions(BinanceSocketClient socketClient,
    IEnumerable<Coin> coins)
{
    List<Task<CallResult<UpdateSubscription>>> tasks =
        new List<Task<CallResult<UpdateSubscription>>>();
    int index = 0;

    foreach (var coin in coins)
    {
        var subs = Utility.AddNewSubscription(socketClient, coin);
        Console.WriteLine("{0}/{1} : {2}", index, coins.Count(), coin.Symbol);
        ++index;

        tasks.Union(subs);
    }

    //foreach(var task in tasks)
    //  Utility.ActiveSubscriptions.Add ( coin.Symbol, task.Result.Data );

    await Task.WhenAll(tasks);
}




public async static Task<List<CallResult<UpdateSubscription>>> AddNewSubscription ( BinanceSocketClient socketClient, IEnumerable<Coin> coins )
{
    var tasks = new List<Task<CallResult<UpdateSubscription>>> ( );
    var taskdict = new Dictionary<string, List<Task<CallResult<UpdateSubscription>>>> ( );

    foreach ( var coin in coins )
    {
        var subtasks = Utility.CreateSubscriptionTasks ( socketClient, coin );
        tasks.AddRange ( subtasks );

        taskdict.Add ( coin.Symbol, subtasks );
    }

    await Task.WhenAll ( tasks );

    foreach ( var task in taskdict )
    {
        var subs = task.Value.Select ( x => x.Result.Data ).ToList ( );
        Utility.ActiveSubscriptions.Add ( task.Key, subs );
    }

    return tasks.Select ( x => x.Result ).ToList ( );
}

Don't call .Result unless you want to block the thread and wait for the result. In this case you probably don't want to wait for the result until the very end, after all the tasks have been started.

public static List<Task<CallResult<UpdateSubscription>>> AddNewSubscription ( BinanceSocketClient socketClient, Coin coin )
{
    var tasks = new List<Task<CallResult<UpdateSubscription>>> ( );

    var sub = socketClient.Spot.SubscribeToSymbolTickerUpdatesAsync ( coin.SymbolPair, data =>
    {
        coin.Price = data.LastPrice;
        coin.LowestDailyPrice = data.LowPrice;
        coin.HighestDailyPrice = data.HighPrice;
        coin.PriceChangeInPercentDaily = data.PriceChangePercent;
    } );
    tasks.Add ( sub );

    sub = socketClient.Spot.SubscribeToKlineUpdatesAsync ( coin.SymbolPair, KlineInterval.OneHour, data =>
    {
        coin.LastHourOpenPrice = data.Data.Open;
        coin.LastHourVolume = data.Data.BaseVolume;
        coin.TotalBuyVolume = data.Data.TakerBuyBaseVolume;
        coin.TotalSellVolume = coin.LastHourVolume - coin.TotalBuyVolume;
    } );
    tasks.Add ( sub );

    sub = socketClient.Spot.SubscribeToKlineUpdatesAsync ( coin.SymbolPair, KlineInterval.OneMinute, data =>
    {
        coin.LastMinuteOpenPrice = data.Data.Open;
    } );
    tasks.Add ( sub );

    //Here is where we wait for them all to complete in parallel
    Task.WaitAll( tasks );
    var subs = tasks.Select( x => x.Result.Data ).ToList(); 

    Utility.ActiveSubscriptions.Add ( coin.Symbol, subs );

    return tasks;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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