Я прочитал несколько тем stackoverflow о многопоточности в цикле foreach, но не уверен, что правильно понимаю и правильно ее использую.
Я пробовал несколько сценариев, но это не так. наблюдая значительное увеличение производительности.
Вот что, по моему мнению, запускает асинхронные задачи, но выполняется синхронно в цикле с использованием одного потока:< /p>
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
foreach (IExchangeAPI selectedApi in selectedApis)
{
if (exchangeSymbols.TryGetValue(selectedApi.Name, out symbol))
{
ticker = await selectedApi.GetTickerAsync(symbol);
}
}
stopWatch.Stop();
Вот то, на что я надеялся работать асинхронно (все еще используя один поток) – я ожидал некоторое улучшение скорости уже здесь:
List exchTkrs = new List();
stopWatch.Start();
foreach (IExchangeAPI selectedApi in selectedApis)
{
if (exchangeSymbols.TryGetValue(selectedApi.Name, out symbol))
{
exchTkrs.Add(selectedApi.GetTickerAsync(symbol));
}
}
ExchangeTicker[] retTickers = await Task.WhenAll(exchTkrs);
stopWatch.Stop();
Вот что я хотел бы запустить асинхронно в многопоточном режиме:
stopWatch.Start();
Parallel.ForEach(selectedApis, async (IExchangeAPI selectedApi) =>
{
if (exchangeSymbols.TryGetValue(selectedApi.Name, out symbol))
{
ticker = await selectedApi.GetTickerAsync(symbol);
}
});
stopWatch.Stop();
Результаты секундомера интерпретируются следующим образом:
Console.WriteLine("Time elapsed (ns): {0}", stopWatch.Elapsed.TotalMilliseconds * 1000000);
Выводы консоли:
Time elapsed (ns): 4183308100
Time elapsed (ns): 4183946299.9999995
Time elapsed (ns): 4188032599.9999995
Теперь улучшение скорости выглядит незначительным. Я делаю что-то не так или это более или менее то, чего мне следует ожидать? Полагаю, лучше это проверить при записи в файлы.
Не могли бы вы также подтвердить, что я правильно интерпретирую различные варианты использования?
Наконец, использование цикла foreach для параллельного получения тикера с нескольких платформ может быть не лучшим подходом. Будем рады предложениям по улучшению.
РЕДАКТИРОВАТЬ
Обратите внимание, что я использую базу кода ExchangeSharp. который вы можете найти здесь
Вот как выглядит метод GerTickerAsync():
public virtual async Task GetTickerAsync(string marketSymbol)
{
marketSymbol = NormalizeMarketSymbol(marketSymbol);
return await Cache.CacheMethod(MethodCachePolicy, async () => await OnGetTickerAsync(marketSymbol), nameof(GetTickerAsync), nameof(marketSymbol), marketSymbol);
}
Для API Kraken у вас есть:
protected override async Task OnGetTickerAsync(string marketSymbol)
{
JToken apiTickers = await MakeJsonRequestAsync("/0/public/Ticker", null, new Dictionary { { "pair", NormalizeMarketSymbol(marketSymbol) } });
JToken ticker = apiTickers[marketSymbol];
return await ConvertToExchangeTickerAsync(marketSymbol, ticker);
}
И метод кэширования:
public static async Task CacheMethod(this ICache cache, Dictionary methodCachePolicy, Func method, params object?[] arguments) where T : class
{
await new SynchronizationContextRemover();
methodCachePolicy.ThrowIfNull(nameof(methodCachePolicy));
if (arguments.Length % 2 == 0)
{
throw new ArgumentException("Must pass function name and then name and value of each argument");
}
string methodName = (arguments[0] ?? string.Empty).ToStringInvariant();
string cacheKey = methodName;
for (int i = 1; i < arguments.Length;)
{
cacheKey += "|" + (arguments[i++] ?? string.Empty).ToStringInvariant() + "=" + (arguments[i++] ?? string.Empty).ToStringInvariant("(null)");
}
if (methodCachePolicy.TryGetValue(methodName, out TimeSpan cacheTime))
{
return (await cache.Get(cacheKey, async () =>
{
T innerResult = await method();
return new CachedItem(innerResult, CryptoUtility.UtcNow.Add(cacheTime));
})).Value;
}
else
{
return await method();
}
}
Подробнее здесь: https://stackoverflow.com/questions/615 ... reach-loop
Многопоточность в цикле foreach ⇐ C#
Место общения программистов C#
1731627913
Anonymous
Я прочитал несколько тем stackoverflow о многопоточности в цикле foreach, но не уверен, что правильно понимаю и правильно ее использую.
Я пробовал несколько сценариев, но это не так. наблюдая значительное увеличение производительности.
Вот что, по моему мнению, [b]запускает асинхронные задачи[/b], но выполняется синхронно в цикле с использованием [b]одного потока[/b]:< /p>
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
foreach (IExchangeAPI selectedApi in selectedApis)
{
if (exchangeSymbols.TryGetValue(selectedApi.Name, out symbol))
{
ticker = await selectedApi.GetTickerAsync(symbol);
}
}
stopWatch.Stop();
Вот то, на что я надеялся [b]работать асинхронно[/b] (все еще используя [b]один поток[/b]) – я ожидал некоторое улучшение скорости уже здесь:
List exchTkrs = new List();
stopWatch.Start();
foreach (IExchangeAPI selectedApi in selectedApis)
{
if (exchangeSymbols.TryGetValue(selectedApi.Name, out symbol))
{
exchTkrs.Add(selectedApi.GetTickerAsync(symbol));
}
}
ExchangeTicker[] retTickers = await Task.WhenAll(exchTkrs);
stopWatch.Stop();
Вот что я хотел бы запустить [b]асинхронно в многопоточном режиме[/b]:
stopWatch.Start();
Parallel.ForEach(selectedApis, async (IExchangeAPI selectedApi) =>
{
if (exchangeSymbols.TryGetValue(selectedApi.Name, out symbol))
{
ticker = await selectedApi.GetTickerAsync(symbol);
}
});
stopWatch.Stop();
Результаты секундомера интерпретируются следующим образом:
Console.WriteLine("Time elapsed (ns): {0}", stopWatch.Elapsed.TotalMilliseconds * 1000000);
Выводы консоли:
Time elapsed (ns): 4183308100
Time elapsed (ns): 4183946299.9999995
Time elapsed (ns): 4188032599.9999995
Теперь улучшение скорости выглядит незначительным. Я делаю что-то не так или это более или менее то, чего мне следует ожидать? Полагаю, лучше это проверить при записи в файлы.
Не могли бы вы также подтвердить, что я правильно интерпретирую различные варианты использования?
Наконец, использование цикла foreach для параллельного получения тикера с нескольких платформ может быть не лучшим подходом. Будем рады предложениям по улучшению.
РЕДАКТИРОВАТЬ
Обратите внимание, что я использую базу кода ExchangeSharp. который вы можете найти здесь
Вот как выглядит метод GerTickerAsync():
public virtual async Task GetTickerAsync(string marketSymbol)
{
marketSymbol = NormalizeMarketSymbol(marketSymbol);
return await Cache.CacheMethod(MethodCachePolicy, async () => await OnGetTickerAsync(marketSymbol), nameof(GetTickerAsync), nameof(marketSymbol), marketSymbol);
}
Для API Kraken у вас есть:
protected override async Task OnGetTickerAsync(string marketSymbol)
{
JToken apiTickers = await MakeJsonRequestAsync("/0/public/Ticker", null, new Dictionary { { "pair", NormalizeMarketSymbol(marketSymbol) } });
JToken ticker = apiTickers[marketSymbol];
return await ConvertToExchangeTickerAsync(marketSymbol, ticker);
}
И метод кэширования:
public static async Task CacheMethod(this ICache cache, Dictionary methodCachePolicy, Func method, params object?[] arguments) where T : class
{
await new SynchronizationContextRemover();
methodCachePolicy.ThrowIfNull(nameof(methodCachePolicy));
if (arguments.Length % 2 == 0)
{
throw new ArgumentException("Must pass function name and then name and value of each argument");
}
string methodName = (arguments[0] ?? string.Empty).ToStringInvariant();
string cacheKey = methodName;
for (int i = 1; i < arguments.Length;)
{
cacheKey += "|" + (arguments[i++] ?? string.Empty).ToStringInvariant() + "=" + (arguments[i++] ?? string.Empty).ToStringInvariant("(null)");
}
if (methodCachePolicy.TryGetValue(methodName, out TimeSpan cacheTime))
{
return (await cache.Get(cacheKey, async () =>
{
T innerResult = await method();
return new CachedItem(innerResult, CryptoUtility.UtcNow.Add(cacheTime));
})).Value;
}
else
{
return await method();
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/61520919/multi-threading-in-a-foreach-loop[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия