如何并行/异步这个方法?



我正试图以一种不会阻塞程序的方式编写此代码。client. point . market . getklinesasync支持等待,但不确定如何构建代码,使其可以等待。

public static async Task GetMinMaxValues ( BinanceClient client, ObservableCollection<Coin> coins )
{
foreach ( var coin in coins )
{
var task = client.Spot.Market.GetKlinesAsync ( coin.SymbolPair, KlineInterval.OneDay );
coin.MinVal = klines.Result.Data.Select ( k => k.Low ).Min ( );
coin.MaxVal = klines.Result.Data.Select ( k => k.High ).Max ( );
}
}

让我困惑的是我如何才能实现这一点,因为我需要能够计算最小值和最大值。如果我访问Result,这个函数就会立即执行,对吧?

所以我不知道如何并行地实现这个计算。

只需创建嵌套异步操作以获取单个Coin的最小/最大,然后并行运行:

public static async Task GetMinMaxValues ( BinanceClient client, 
ObservableCollection<Coin> coins )
{
await Task.WhenAll(coins.Select(async c=>await GetMinMax(c, client)).ToList());
}
public static async Task GetMinMax(Coin coin, BinanceClient client)
{
var res = await client.Spot.Market.GetKlinesAsync ( coin.SymbolPair );
coin.MinVal = klines.Result.Data.Select ( k => k.Low ).Min ( );
coin.MaxVal = klines.Result.Data.Select ( k => k.High ).Max ( );
}

这种方法的危险可能是,当您有很多Coins时,您将在同一时刻创建一大堆任务。如果是这种情况,那么您可以额外执行某种工作分区到适当大小的块。

为了不阻塞UI,您不需要并行地执行此操作。只是await的异步方法调用。目前还不清楚GetKlinesAsync返回的确切内容,但这样的东西可以在不阻塞UI的情况下工作(假设该方法是io绑定的,并且假设您的计算相当快):

public static async Task GetMinMaxValues(BinanceClient client, ObservableCollection<Coin> coins)
{
foreach (var coin in coins)
{
//Invokes asynchronous get method, waits for it to finish, and gets the result
var result = await client.Spot.Market.GetKlinesAsync(coin.SymbolPair, KlineInterval.OneDay);
//Use the result to set your coin values
coin.MinVal = result.Data.Select(k => k.Low).Min();
coin.MaxVal = result.Data.Select(k => k.High).Max();
}
}

如果你想并行运行调用来加速执行,你可以这样做,但这不是必要的,以防止方法调用阻塞调用线程。

考虑阅读Microsoft关于基于任务的异步编程的文档。如果你不真正了解Tasksasyncawait是如何在基本层面上工作的,那么前面有很多陷阱。

最新更新