Как ускорить парсинг цен на монеты Binance?

Я пытаюсь создать бота, который размещает несколько ордеров на Binance, и мне нужен быстрый анализ цен на монеты.

Я разбираю код, используя этот код

Dim price as decimal       
Private Async Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    Timer1.Stop()
    Dim downloadTasks As New List(Of Task(Of String))
    Dim dogebusd = wc1.DownloadStringTaskAsync("https://api.binance.com/api/v1/ticker/price?symbol=DOGEBUSD")
    downloadTasks.Add(dogebusd)
    Await Task.WhenAll(downloadTasks)

    Dim d = JsonConvert.DeserializeObject(Of Dictionary(Of String, String))(dogebusd.Result)
    Dim PREZZO As Decimal = CDec(Val((d("price")).ToString))
    
    price = CDec((PREZZO))
    
    Timer1.Start()
End Sub

но когда цена демпингует или качается очень быстро, даже таймер на 10 мс или 100 мс не так эффективен. Интересно, это самый быстрый способ или я могу улучшить код? Спасибо

следующие предложения Джими:

Dim price As Decimal
Private ReadOnly _timer As New PeriodicTimer(TimeSpan.FromSeconds(1))

Private Async Sub Timer1_Tick(sender As Object, e As EventArgs) Handles _timer.Tick
    timer1.stop
    Dim dogebusdTask = HttpClient.GetStringAsync("https://api.binance.com/api/v1/ticker/price?symbol=DOGEBUSD")
    Await dogebusdTask
    Dim d = JsonConvert.DeserializeObject(Of Dictionary(Of String, String))(dogebusdTask.Result)
    If Decimal.TryParse(d("price"), NumberStyles.Number, CultureInfo.InvariantCulture, price) Then
        _timer.Start()
    End If
End Sub

у вас всегда будет задержка при получении веб-сайта, почему бы не запустить скрипт на вашем сервере, который имеет лучшее соединение с сайтом. Парсинг будет быстрым, так как он получит только 2 значения, но веб-сайту требуется 346 мс, чтобы ответить даже на линии 100 мегабайт. поэтому, пока вы не можете получить более быстрые результаты, вы не получите более быстрого ответа

nbk 05.02.2023 00:59

хм, у меня вообще нет сервера

Mattia 05.02.2023 01:04

интересно, есть ли у Binance HTTP-методы GET, которые могут обновить мою метку, и будет ли это быстрее

Mattia 05.02.2023 01:07

Сервер обычно имеет по крайней мере гигабитные соединения Ethernet, и сервер рядом с веб-сайтом будет очень быстрым.

nbk 05.02.2023 01:08

нет сайт запрещает htto запросы

nbk 05.02.2023 01:09

Хорошо, это часть, что вы думаете о моем коде? вы бы улучшить его?

Mattia 05.02.2023 01:14

я не понимаю, почему вы удваиваете значение CDec, во-вторых, проверьте скорость синтаксического анализатора json, возможно, доступен другой более быстрый метод, так как есть другие синтаксические анализаторы json

nbk 05.02.2023 01:32
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
7
104
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Пример использования ожидаемого PeriodicTimer и System.Text.Json .NET 6+ для анализа результирующего потока, возвращаемого функцией GetStreamAsync() HttpClient.

PeriodicTimer может быть весьма эффективным в таких контекстах, поскольку он пытается не отставать от заданного вами интервала. Поскольку для выполнения внутренней процедуры требуется время - HttpClient.GetStreamAsync() требуется неопределенное количество времени для выполнения и возврата результата - Таймер отслеживает фактическое прошедшее время и пытается постоянно тикать (если только процедура не занимает больше указанного интервала, тогда ты промахиваешься, конечно)

  • Примечание: как обычно, при работе с задачами, которые принимают CancellationToken, вы должны запускать этот код без отладчика (CTRL+F5) или настроить отладчик так, чтобы он не останавливался на TaskCanceledException или OperationCanceledException, в противном случае он обрабатывает (игнорируемое) исключение до того, как вы это сделаете.

Imports System.Globalization
Imports System.Net.Http
Imports System.Text.Json
Imports System.Threading

Private Shared ReadOnly m_Client As New HttpClient()
Private timerCts As CancellationTokenSource = Nothing
Private m_PeriodicTimer As PeriodicTimer = Nothing
Private m_PeriodicTimerInterval As Integer = 500
Private currentPrice As Decimal = 0.0D

Private Async Function StartPriceLookupTimer(token As CancellationToken, timerInterval As Integer) As Task
    If token.IsCancellationRequested Then Return
    Dim lookupAddress = "https://api.binance.com/api/v1/ticker/price?symbol=DOGEBUSD"
    m_PeriodicTimer = New PeriodicTimer(TimeSpan.FromMilliseconds(timerInterval))
    Try
        While Await m_PeriodicTimer.WaitForNextTickAsync(token)
            Dim jsonStream = Await m_Client.GetStreamAsync(lookupAddress, token)
            Try
                Dim prop = (Await JsonDocument.ParseAsync(jsonStream, Nothing, token)).RootElement.GetProperty("price")
                Dim strPrice = prop.GetString()
                If Decimal.TryParse(strPrice, CultureInfo.InvariantCulture, currentPrice) Then
                ' Do whatever you need to do with the parsed value
                ' E.g., assign it to a TextBox for presentation, 
                ' using the current Culture format, since strPrice contains the original format
                    [Some TextBox].Text = currentPrice.ToString() ' <= UI Thread here
                End If
            Catch knfex As KeyNotFoundException
                Debug.WriteLine("The JSON property was not found")
            Catch tcex As TaskCanceledException
                Debug.WriteLine("The lookup procedure was canceled")
            End Try
        End While
    Catch tcex As TaskCanceledException
        Debug.WriteLine("The lookup procedure was canceled")
    End Try
End Function

Private Sub StopPriceLookupTimer()
    timerCts?.Cancel()
    m_PeriodicTimer?.Dispose()
    timerCts?.Dispose()
    timerCts = Nothing
End Sub

Как запустить эту процедуру поиска, вызвав метод StartPriceLookupTimer()?
Вы можете использовать кнопку, сделав ее обработчик кликов асинхронным:

Private Async Sub SomeButton_Click(sender As Object, e As EventArgs) Handles SomeButton.Click
    If timerCts Is Nothing Then
        timerCts = New CancellationTokenSource()
        Await StartPriceLookupTimer(timerCts.Token, m_PeriodicTimerInterval)
    Else
        Debug.WriteLine("Lookup Timer already started")
    End If
End Sub

Или сделайте так, чтобы метод Shown Handler / OnShown() формы переопределял асинхронность и запускал процедуру при первом представлении формы:

Protected Overrides Async Sub OnShown(e As EventArgs)
    MyBase.OnShown(e)
    timerCts = New CancellationTokenSource()
    Await StartPriceLookupTimer(timerCts.Token, m_PeriodicTimerInterval)
End Sub

Чтобы остановить процедуру поиска, при необходимости вызовите метод StopPriceLookupTimer(), например, с помощью другой кнопки или в обработчике Form.Closed/переопределении OnFormClosed()

У меня нет слов.. это даже быстрее, чем то, что показывает веб-сайт.. Спасибо, ДЖИМИ !!!!! так держать

Mattia 06.02.2023 02:47

Джими просто вещь.. Можно ли перенести проект фреймворка на .net 6+? все, что я могу прочитать в Интернете, это только о переходе с .net framework на .net, но не о том, как это сделать. Нужно ли мне заново создавать весь дизайн?

Mattia 06.02.2023 03:17
Обзор переноса с .NET Framework на .NET -- Основные проблемы, которые могут у вас возникнуть, связаны с пакетами NuGet (и их зависимостями, если таковые имеются), которые могут быть недоступны для .NET (ни один из основных инструментов) и редкие инструменты, которые сейчас устарели в .NET (как WebClient). В остальном это в основном то же самое (т. Е. Не требуется перепроектирование, дизайнеры .NET совместимы с .NET Framework)
Jimi 06.02.2023 04:23

хм, я использую Binance.net, разработанный JKorf, но кажется, что он доступен для .net, может быть, я ошибаюсь. Как мне перенести форму, которую я создал для .net framework, в .net 6+? смотри [ссылка]imgur.com/a/Dbdo2L1

Mattia 06.02.2023 04:57

Пакет, который вы упомянули, доступен для .NET 7, так что проблем нет. Документация по инструменту миграции, на которую я дал ссылку, помогает перенести стиль проекта из msbuild в новый Microsoft.NET.Sdk, включая все внешние зависимости. Делать больше нечего, Forms и Controls абсолютно одинаковы (что касается сериализатора). Если вы хотите, вы можете импортировать форму, созданную в .NET Framework, в проект .NET 7 как есть.

Jimi 06.02.2023 05:04

это прекрасно, я только что поменял местами файлы формы, и это работает как шарм! Еще раз спасибо! Было приятно читать Вас снова!!!

Mattia 06.02.2023 05:15

не могли бы вы предложить мне использовать PeriodicTimer и для других вещей, которые я делаю? лайк проверить открытые заказы и т. д. ссылка

Mattia 06.02.2023 05:44

Почему нет? Это Таймер. Это ожидаемо и очень просто в использовании, очень хорошо вписывается в эту платформу. Помните, что это не может быть передано. Один таймер для каждой задачи. Выбрасывайте его, когда он больше не нужен. Создайте его новым (как показано здесь), если / когда это необходимо. Или используйте только для чтения, если его задача не меняется в течение всего срока службы.

Jimi 06.02.2023 06:05

Другие вопросы по теме