Я пытаюсь создать бота, который размещает несколько ордеров на 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
хм, у меня вообще нет сервера
интересно, есть ли у Binance HTTP-методы GET, которые могут обновить мою метку, и будет ли это быстрее
Сервер обычно имеет по крайней мере гигабитные соединения Ethernet, и сервер рядом с веб-сайтом будет очень быстрым.
нет сайт запрещает htto запросы
Хорошо, это часть, что вы думаете о моем коде? вы бы улучшить его?
я не понимаю, почему вы удваиваете значение CDec, во-вторых, проверьте скорость синтаксического анализатора json, возможно, доступен другой более быстрый метод, так как есть другие синтаксические анализаторы json
Пример использования ожидаемого PeriodicTimer и System.Text.Json .NET 6+ для анализа результирующего потока, возвращаемого функцией GetStreamAsync() HttpClient.
PeriodicTimer может быть весьма эффективным в таких контекстах, поскольку он пытается не отставать от заданного вами интервала. Поскольку для выполнения внутренней процедуры требуется время - HttpClient.GetStreamAsync()
требуется неопределенное количество времени для выполнения и возврата результата - Таймер отслеживает фактическое прошедшее время и пытается постоянно тикать (если только процедура не занимает больше указанного интервала, тогда ты промахиваешься, конечно)
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()
У меня нет слов.. это даже быстрее, чем то, что показывает веб-сайт.. Спасибо, ДЖИМИ !!!!! так держать
Джими просто вещь.. Можно ли перенести проект фреймворка на .net 6+? все, что я могу прочитать в Интернете, это только о переходе с .net framework на .net, но не о том, как это сделать. Нужно ли мне заново создавать весь дизайн?
хм, я использую Binance.net, разработанный JKorf, но кажется, что он доступен для .net, может быть, я ошибаюсь. Как мне перенести форму, которую я создал для .net framework, в .net 6+? смотри [ссылка]imgur.com/a/Dbdo2L1
Пакет, который вы упомянули, доступен для .NET 7, так что проблем нет. Документация по инструменту миграции, на которую я дал ссылку, помогает перенести стиль проекта из msbuild в новый Microsoft.NET.Sdk
, включая все внешние зависимости. Делать больше нечего, Forms и Controls абсолютно одинаковы (что касается сериализатора). Если вы хотите, вы можете импортировать форму, созданную в .NET Framework, в проект .NET 7 как есть.
это прекрасно, я только что поменял местами файлы формы, и это работает как шарм! Еще раз спасибо! Было приятно читать Вас снова!!!
не могли бы вы предложить мне использовать PeriodicTimer и для других вещей, которые я делаю? лайк проверить открытые заказы и т. д. ссылка
Почему нет? Это Таймер. Это ожидаемо и очень просто в использовании, очень хорошо вписывается в эту платформу. Помните, что это не может быть передано. Один таймер для каждой задачи. Выбрасывайте его, когда он больше не нужен. Создайте его новым (как показано здесь), если / когда это необходимо. Или используйте только для чтения, если его задача не меняется в течение всего срока службы.
у вас всегда будет задержка при получении веб-сайта, почему бы не запустить скрипт на вашем сервере, который имеет лучшее соединение с сайтом. Парсинг будет быстрым, так как он получит только 2 значения, но веб-сайту требуется 346 мс, чтобы ответить даже на линии 100 мегабайт. поэтому, пока вы не можете получить более быстрые результаты, вы не получите более быстрого ответа